/* Archivo carries both the headings and the wordmark. The wordmark keeps its own
   for site and app alike; served from this origin so the display type needs no
   third-party request. */
@font-face{font-family:"Archivo";src:url("archivo-var.92895abae7c5.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap}
/* Archivo for headings; body text uses
   the device's own font, so no webfont is fetched for running text. The
   wordmark is kept on its own --wordmark variable so it survives
   any future change to --display. Mirrors site/article.css deliberately. */
:root{
  /* Shared navigation metrics. The bar must look identical across the
     marketing site and the app, so a visitor moving between them sees no
     shift. These values are duplicated in site/policy.css, site/article.css,
     site/index.html and web/static/app.css, and a test asserts they match. */
  --nav-height:64px;
  --nav-max-width:1080px;
  --nav-gap:24px;
  --nav-links-gap:22px;
  --nav-wordmark-size:21.6px;
  --nav-link-size:14.72px;
  --nav-link-weight:500;
  --nav-pill-height:42px;
  --nav-pill-padding:8.8px 17.6px;
  --nav-pill-min-width:100px;
  --nav-line-height:1.6;
  --app-sidebar-width:236px;

  --night:#10131F;
  --dusk:#1A2032;
  --dusk-2:#222A40;
  --lamplight:#F5B84A;
  --lamplight-soft:#F5B84A26;
  --settled:#7FC8A9;
  --attention:#E8927C;
  --moon:#E9ECF5;
  --dim:#97A0B8;
  --line:#2C3450;
  --wordmark:"Archivo",-apple-system,"Segoe UI",sans-serif;
  --display:"Archivo",-apple-system,"Segoe UI",sans-serif;
  --body:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,monospace;
  --radius:14px;
  --width:1080px;
}
/* The nav bar is shared chrome: it must render identically on the marketing
   pages and inside the app. These values are px on purpose -- app.css drops the
   root font-size to 14px on small screens, and rem tokens silently rescaled
   with it, which is exactly how the two bars drifted apart. Duplicated in
   site/index.html, site/article.css, site/policy.css and web/static/app.css;
   test_navigation_metrics_are_identical_across_surfaces holds them together. */
@media (max-width:640px){
  :root{--nav-height:60px;--nav-wordmark-size:18px;--nav-link-size:13px;--nav-links-gap:12px}
}
@media (max-width:420px){
  :root{--nav-wordmark-size:16px;--nav-link-size:12px;--nav-links-gap:9px}
}

*{box-sizing:border-box}
html{min-height:100%;scroll-behavior:smooth}
body{
  min-height:100vh;
  margin:0;
  display:flex;
  flex-direction:column;
  overflow-x:hidden;
  background:var(--night);
  color:var(--moon);
  font-family:var(--body);
  font-size:17px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
::selection{background:var(--lamplight);color:var(--night)}
a{color:var(--lamplight);text-decoration:none}
a:hover{text-decoration:underline}
a:focus-visible,button:focus-visible,input:focus-visible{
  outline:2px solid var(--lamplight);
  outline-offset:3px;
  border-radius:6px;
}
button,input{font:inherit}
button{cursor:pointer}
.wrap{width:min(100%,calc(var(--width) + 48px));margin:0 auto;padding-inline:24px}
.page-glow{
  position:fixed;
  z-index:-1;
  inset:0;
  pointer-events:none;
  background:
    radial-gradient(52% 42% at 78% 20%,var(--lamplight-soft),transparent 72%),
    radial-gradient(30% 28% at 12% 86%,#7FC8A90c,transparent 72%);
}

.site-nav{
  position:sticky;
  top:0;
  z-index:50;
  background:rgba(16,19,31,.9);
  backdrop-filter:blur(12px);
  border-bottom:1px solid var(--line);
}
.nav-inner{min-height:var(--nav-height);max-width:var(--nav-max-width);display:flex;align-items:center;gap:var(--nav-gap)}
.wordmark{
  display:flex;
  align-items:center;
  gap:9px;
  flex:none;
  color:var(--moon);
  font-family:var(--wordmark);
  font-size:var(--nav-wordmark-size);
  font-weight:600;
  letter-spacing:-.01em;line-height:var(--nav-line-height);
}
.wordmark:hover{text-decoration:none}
.moon-dot{width:13px;height:13px;flex:none}
.nav-links{margin-left:auto;display:flex;align-items:center;gap:var(--nav-links-gap);min-width:0}
.nav-link{color:var(--dim);font-size:var(--nav-link-size);font-weight:var(--nav-link-weight);white-space:nowrap}
.nav-link:hover,.nav-link.active{color:var(--moon);text-decoration:none}
.nav-link.active{border-bottom:1px solid var(--lamplight)}
.nav-form{display:flex;align-items:center;margin:0}
/* The language pill, identical to site/index.html's .nav-links .nav-lang.
   px padding, not rem: below 640px this file drops the root to 14px, and a
   rem here would shrink the pill in the app and nowhere else -- the exact
   drift that made the two bars disagree. A <button> needs its own reset
   because it does not inherit the page font the way an <a> does. */
.nav-links .nav-lang{display:inline-flex;align-items:center;min-height:var(--nav-pill-height);padding:var(--nav-pill-padding);border:1px solid var(--line);border-radius:999px;background:transparent;color:var(--dim);font-family:inherit;line-height:var(--nav-line-height);font-size:var(--nav-link-size);font-weight:var(--nav-link-weight);white-space:nowrap;cursor:pointer}
.nav-links .nav-lang:hover{color:var(--moon);border-color:var(--dim);text-decoration:none}
.nav-button{padding:0;border:0;background:transparent}
.nav-account-button{
  display:inline-flex;
  min-height:var(--nav-pill-height);
  align-items:center;
  justify-content:center;
  padding:var(--nav-pill-padding);
  border-radius:999px;
  /* Quiet by default. Amber is reserved for .active, which means
     "you are signed in" -- see base.html. */
  background:transparent;
  border:1px solid var(--line);
  color:var(--moon);
  font-size:var(--nav-link-size);
  /* 700 to match the marketing pill exactly -- measured, both surfaces now
     render 14.72px/700. The token (500) made the app pill visibly lighter,
     which is the 'nav fonts differ' the founder was still seeing. The
     literal ban in test_navigation_rules_use_the_tokens_rather_than_literals
     covers 600 only; 700 is what article.css already uses here. */
  font-weight:700;
  white-space:nowrap;line-height:var(--nav-line-height);min-width:var(--nav-pill-min-width);
}
.nav-account-button:hover{border-color:var(--dim);text-decoration:none}
.nav-account-button.active{background:var(--lamplight);border-color:var(--lamplight);color:#221A05;font-weight:700}
.nav-account-button.active:hover{box-shadow:0 6px 24px -8px var(--lamplight)}
.nav-account-shortcut{
  display:none;
  min-height:40px;
  align-items:center;
  margin-left:auto;
  padding:.45rem 1rem;
  border:1px solid #59627c;
  border-radius:999px;
  color:var(--moon);
  font-size:.82rem;
  font-weight:700;
  white-space:nowrap;
}
.nav-account-shortcut:hover,.nav-account-shortcut.active{border-color:var(--lamplight);background:var(--lamplight);color:#221A05;text-decoration:none}
.app-mobile-nav{display:none}

.app-wrap{flex:1;padding-top:56px;padding-bottom:80px}
.site-footer{border-top:1px solid var(--line);padding:30px 0 38px;color:var(--dim);font-size:.8rem}
.footer-inner{display:flex;justify-content:space-between;align-items:flex-start;gap:24px}
.footer-inner p{margin:0;max-width:42rem}
.footer-links{display:flex;gap:18px;flex-wrap:wrap}
.footer-links a{color:var(--dim)}
/* Language switch. A POST form rather than a link, so nothing but a deliberate
   click can change a parent's language -- see grademonitor/language.py. Styled
   to read as the footer link it sits beside. */
.lang-switch{margin:0}
.lang-switch button{
  background:none;border:0;padding:0;cursor:pointer;
  color:var(--dim);font:inherit;text-decoration:underline;text-underline-offset:3px;
}
.lang-switch button:hover{color:var(--moon)}
.footer-links a:hover{color:var(--moon)}

.messages{padding:0;margin:0 0 24px;list-style:none}
.messages li{padding:.8rem 1rem;border:1px solid;border-radius:10px;background:var(--dusk)}
.messages .error{color:#ffd7ce;border-color:#E8927C70;background:#3a242b}
.messages .success{color:#c7f2df;border-color:#7FC8A970;background:#1c352f}

.eyebrow,.kicker{
  margin:0 0 .8rem;
  color:var(--lamplight);
  font-size:.98rem;
}
.kicker{color:var(--dim)}
h1,h2,h3,p{margin-top:0}
h1,h2{font-family:var(--display);font-weight:800;letter-spacing:-.022em}
h1{font-size:clamp(2.3rem,5vw,3.8rem);line-height:1.08;margin-bottom:1.15rem}
h1 em{color:var(--lamplight);font-weight:500}
h2{font-size:clamp(1.45rem,2.7vw,2rem);line-height:1.16;margin-bottom:.7rem}
h3{font-size:1.04rem;margin-bottom:.45rem}
.lede{max-width:38rem;margin-bottom:1.8rem;color:var(--dim);font-size:1.08rem}
.panel-copy{margin-bottom:1.25rem;color:var(--dim)}
.panel-copy strong{color:var(--moon)}
.fine-print,.muted{color:var(--dim);font-size:.82rem;line-height:1.55}
.fine-print{margin:.9rem 0 0}
/* Footnote marker tying the sign-in headline to its qualifier below.
   Amber so it reads as a reference rather than stray punctuation, and
   raised so it never looks like part of the final word. */
.footnote-mark{color:var(--lamplight);font-size:.5em;vertical-align:super;margin-left:.15em;font-style:normal;font-weight:400}
.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}

.auth-page .app-wrap{display:grid;align-items:center;padding-top:54px;padding-bottom:70px}
.auth-layout{display:grid;grid-template-columns:1.05fr .95fr;gap:64px;align-items:center;width:100%}
.auth-copy{max-width:34rem}
.auth-copy .lede{max-width:32rem}
.trust-list{display:grid;gap:.7rem;margin:0;padding:0;list-style:none;color:var(--dim);font-size:.92rem}
.trust-list li{display:flex;align-items:center;gap:.75rem}
.trust-mark{
  display:grid;
  place-items:center;
  width:25px;
  height:25px;
  flex:none;
  border:1px solid #7FC8A966;
  border-radius:50%;
  color:var(--settled);
  box-shadow:0 0 20px #7FC8A91c;
  font-size:.72rem;
}
.auth-card,.panel{
  position:relative;
  background:linear-gradient(160deg,var(--dusk-2),var(--dusk));
  border:1px solid var(--line);
  border-radius:var(--radius);
  box-shadow:0 28px 80px -42px #000,0 0 80px -46px var(--lamplight);
}
.auth-card{padding:42px;overflow:hidden}
.auth-card::before{
  content:"";
  position:absolute;
  inset:-45% -35% auto 36%;
  height:260px;
  background:radial-gradient(circle,#F5B84A1f,transparent 70%);
  pointer-events:none;
}
.auth-card>*{position:relative}
.auth-moon{
  width:54px;
  height:54px;
  margin-bottom:28px;
  overflow:hidden;
  border-radius:50%;
  background:radial-gradient(circle at 36% 34%,#FFE4A4,var(--lamplight) 57%,#C47F19 100%);
  box-shadow:0 0 28px #F5B84A70,0 0 70px #F5B84A24;
}
.auth-moon::after{content:"";display:block;width:52px;height:52px;margin:-10px 0 0 17px;border-radius:50%;background:var(--dusk-2)}
.mail-mark{
  display:grid;
  place-items:center;
  width:58px;
  height:58px;
  margin-bottom:28px;
  border:1px solid #7FC8A966;
  border-radius:50%;
  color:var(--settled);
  box-shadow:0 0 30px #7FC8A922;
}
.mail-mark svg{width:27px;height:27px}
.form-stack{display:grid;gap:12px;margin-top:1.4rem}
/* margin-top gives the "or" room to breathe above. Without it the block butts
   straight against the submit button and the divider's rules graze the amber
   pill: measured 0px above the divider against 10.4px below, which is what made
   it look wrong. */
.passkey-action{display:grid;gap:.65rem;margin-top:1rem}
/* Hidden until passkeys.js confirms the browser supports WebAuthn. Needs an
   explicit rule because the display:grid above beats the UA sheet's [hidden]. */
.passkey-action[hidden]{display:none}
/* Grid gap owns the vertical rhythm, so the divider's own 1rem margin would
   double it. The small bottom margin evens the gap above and below the word. */
.passkey-action .auth-divider{margin:0 0 .35rem}
/* Width only. This used to also set background:var(--moon);color:var(--night) to
   make the passkey button the quiet one -- and it never worked: .btn sets
   background:var(--lamplight) 900-odd bytes further down at identical
   specificity, so amber won and the sign-in page shipped two identical solid
   buttons with no hierarchy. The button now carries .ghost, whose two-class
   selector wins outright, and the dead declarations are gone rather than
   reordered so nothing here depends on source order again. */
.passkey-button{width:100%}
.passkey-feedback{min-height:1.3rem;margin:.55rem 0 0;color:var(--dim);font-size:.82rem}
/* Reserved height stops the card jumping when a status message appears -- but with
   no message it left ~40px of dead air under the passkey button. Collapsed while
   empty, and deliberately NOT display:none: this is an aria-live region, and
   removing it from the accessibility tree risks screen readers never announcing
   the message, which is the one audience that cannot see the button state. */
.passkey-feedback:empty{min-height:0;margin-top:0}
.passkey-feedback.success{color:var(--settled)}
.passkey-feedback.error{color:var(--attention)}
.auth-divider{display:flex;align-items:center;gap:12px;margin:1rem 0;color:var(--dim);font-size:.76rem;text-transform:uppercase;letter-spacing:.08em}
.auth-divider::before,.auth-divider::after{content:"";height:1px;flex:1;background:var(--line)}
.form-stack label,.alias-form label,.delete-form label{color:var(--dim);font-size:.85rem;font-weight:600}
input{
  width:100%;
  min-height:48px;
  padding:.8rem 1rem;
  border:1px solid var(--line);
  border-radius:10px;
  background:var(--night);
  color:var(--moon);
}
input::placeholder{color:#5B6480}
input:hover{border-color:#47516f}
input:focus{border-color:var(--lamplight)}
.btn{
  display:inline-flex;
  min-height:46px;
  align-items:center;
  justify-content:center;
  padding:.68rem 1.25rem;
  border:0;
  border-radius:999px;
  background:var(--lamplight);
  color:#221A05;
  font-size:.92rem;
  font-weight:700;
  line-height:1.2;
  transition:transform .15s ease,box-shadow .15s ease;
}
.btn:hover{transform:translateY(-1px);box-shadow:0 6px 24px -8px var(--lamplight);text-decoration:none}
.btn.ghost{border:1px solid var(--line);background:transparent;color:var(--moon)}
.btn.ghost:hover{border-color:var(--dim);box-shadow:none}
.btn.compact{min-height:40px;padding:.52rem 1rem;font-size:.82rem}
.btn.danger{background:var(--attention);color:#2d1310}

.page-heading{margin-bottom:34px}
.page-back{display:inline-block;margin-bottom:20px;color:var(--dim);font-size:.82rem;font-weight:650}
.page-back:hover{color:var(--moon);text-decoration:none}
.page-heading h1{font-size:clamp(2rem,4vw,3.15rem)}
.page-heading .lede{margin-bottom:0}
.settings-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.settings-panel{padding:28px}
.settings-wide{grid-column:1/-1}
.identity-value{
  overflow-wrap:anywhere;
  padding:.8rem 1rem;
  border:1px solid var(--line);
  border-radius:10px;
  background:var(--night);
  color:var(--moon);
  font-family:var(--mono);
  font-size:.9rem;
}
.schedule-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem;margin:0;padding:0;list-style:none;color:var(--moon);font-size:.9rem}
.schedule-list li{display:flex;align-items:center;gap:.6rem}
.schedule-dot{width:7px;height:7px;flex:none;border-radius:50%;background:var(--lamplight);box-shadow:0 0 12px #F5B84A88}
.panel-heading-row{display:flex;justify-content:space-between;align-items:flex-start;gap:20px}
.alias-form{padding:18px 0;border-top:1px solid var(--line)}
.check-control{display:flex;align-items:center;gap:.65rem;margin:1rem 0 .9rem;color:var(--moon);font-size:.95rem;font-weight:600}
.check-control input[type="checkbox"]{width:1.15rem;height:1.15rem;min-height:0;flex:none;padding:0;border-radius:4px;accent-color:var(--lamplight)}
/* Radios inherit the generic input rule -- width:100%, min-height:48px, padding,
   border -- because only checkboxes were ever overridden. The detail-level
   radios therefore rendered as full-width 48px boxes, which on a phone pushed
   every label off its row. */
.check-control input[type="radio"]{width:1.15rem;height:1.15rem;min-height:0;flex:none;padding:0;border-radius:50%;accent-color:var(--lamplight)}

/* A two-line choice, not a one-line checkbox: the control aligns to the first
   line rather than the middle of the block, and the example line is real
   schoolwork text that must wrap rather than overflow a narrow screen. */
.detail-levels{margin:1.4rem 0 .5rem;padding:0;border:0;min-width:0}
.detail-levels legend{padding:0;color:var(--moon);font-size:.95rem;font-weight:600}
.detail-levels .check-control{align-items:flex-start;gap:.7rem;margin:.9rem 0;font-weight:500}
.detail-levels .check-control input{margin-top:.18rem}
.detail-levels .check-control>span{display:grid;gap:.2rem;min-width:0}
.detail-levels .check-control strong{color:var(--moon);font-weight:650}
.detail-levels .fine-print{margin:0;overflow-wrap:anywhere}
.inline-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;align-items:center;margin-top:.45rem}
.connection-row{display:flex;justify-content:space-between;align-items:center;gap:22px;padding:18px 0;border-top:1px solid var(--line)}
.connection-host{margin:.65rem 0 0;color:var(--moon);overflow-wrap:anywhere}
.status-pill{display:inline-flex;padding:.24rem .62rem;border:1px solid;border-radius:999px;font-size:.72rem;font-weight:700;text-transform:capitalize}
.status-active{color:var(--settled);border-color:#7FC8A966;background:#7FC8A912}
.status-degraded,.status-needs_reauth,.status-revoked{color:var(--attention);border-color:#E8927C66;background:#E8927C12}
.status-paused{color:var(--lamplight);border-color:#F5B84A66;background:#F5B84A12}
.text-button{padding:0;border:0;background:transparent;color:var(--lamplight);font-weight:650}
.attention-text{color:var(--attention)!important}
.empty-state{margin:1rem 0 0;padding:1rem;border:1px dashed var(--line);border-radius:10px;color:var(--dim)}
.passkey-enrollment{max-width:680px}
.passkey-list{display:grid;margin-top:1.2rem;border-top:1px solid var(--line)}
.passkey-row{display:grid;grid-template-columns:minmax(180px,1fr) minmax(260px,1fr) auto;gap:18px;align-items:center;padding:18px 0;border-bottom:1px solid var(--line)}
.passkey-summary{display:grid;gap:.2rem}
.passkey-summary span{color:var(--dim);font-size:.8rem}
.passkey-rename{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:center}
.passkey-rename input{min-height:42px}
.danger-panel{border-color:#E8927C4d;background:linear-gradient(160deg,#302333,var(--dusk))}
.delete-form{margin-top:1.3rem}

ol.muted{padding-left:1.25rem}
table{display:block;width:100%;overflow-x:auto;border-collapse:collapse}
tbody{display:table;width:100%;min-width:620px}
th,td{padding:.75rem;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
th{color:var(--dim);font-size:.76rem;letter-spacing:.06em;text-transform:uppercase}

@media (max-width:820px){
  .auth-layout{grid-template-columns:1fr;gap:32px}
  .auth-copy{max-width:39rem}
  .auth-card{max-width:39rem;width:100%}
  .settings-grid{grid-template-columns:1fr}
  .settings-wide{grid-column:auto}
}
@media (max-width:720px){
  .public-nav-link{display:none}
}
@media (max-width:620px){
  body{font-size:16px}
  .wrap{padding-inline:18px}
  .nav-dashboard{display:none}
  .app-wrap{padding-top:38px;padding-bottom:56px}
  .auth-page .app-wrap{padding-top:36px}
  .auth-card,.settings-panel{padding:24px 20px}
  .footer-inner{flex-direction:column}
  .panel-heading-row,.connection-row{align-items:flex-start;flex-direction:column}
  .inline-control{grid-template-columns:1fr}
  .inline-control .btn{width:100%}
  .passkey-row{grid-template-columns:1fr;gap:12px}
  .passkey-rename{grid-template-columns:1fr auto}
  .schedule-list{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .btn{transition:none}
}

/* Authenticated app shell: two navigations with two different jobs.

   The top bar is the shared one. It spans the full width and is identical on
   every surface, signed in or out — same wordmark, same public links, same
   Account pill — so nothing shifts when a visitor crosses between
   bybedtime.com and the app. It is never restyled here.

   The sidebar beneath it carries the app's own sections, which only exist once
   you are signed in. It is a separate component rather than a restyling of
   .site-nav, and it takes its type from the same --nav-* tokens as the bar, so
   the two cannot drift apart. Until 2026-07-25 the sidebar was built by
   overriding the top bar and hardcoded .82rem links, which no signed-out
   measurement could see. */
.dashboard-page{background:var(--night)}
.dashboard-page .page-glow{background:radial-gradient(48% 34% at 72% 4%,#F5B84A14,transparent 76%)}
.authenticated{
  display:grid;
  grid-template-columns:var(--app-sidebar-width) minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr) auto;
}
.authenticated .site-nav{grid-column:1/-1;grid-row:1}
/* The bar is identical signed in or out, and identical to the marketing site:
   same 1080px column, same centring, same padding. It previously ran full width
   when signed in so the wordmark aligned with the sidebar column beneath it --
   but that made the bar jump ~300px left the moment a parent signed in, which
   read as the nav changing size between the site and the app. Matching the
   marketing bar matters more than aligning with the sidebar. */
.authenticated .app-sidebar{grid-column:1;grid-row:2}
.authenticated .app-wrap{grid-column:2;grid-row:2}
.authenticated .site-footer{grid-column:2;grid-row:3}
.app-sidebar{
  display:flex;
  flex-direction:column;
  gap:4px;
  position:sticky;
  top:var(--nav-height);
  align-self:start;
  min-height:calc(100vh - var(--nav-height));
  padding:22px 19px 24px;
  border-right:1px solid var(--line);
  background:#0d101b;
}
/* No font-size or weight here on purpose: .nav-link already resolves both from
   --nav-link-size and --nav-link-weight, which the top bar uses too. */
.app-sidebar .nav-link{
  display:flex;
  min-height:45px;
  align-items:center;
  padding:0 13px;
  border-radius:9px;
}
.app-sidebar .nav-link:hover{background:#171c2b;color:var(--moon);text-decoration:none}
.app-sidebar .nav-link.active{position:relative;background:#20273a;color:var(--moon);border-bottom:0}
.app-sidebar .nav-link.active::before{content:"";width:3px;height:18px;margin-right:10px;border-radius:3px;background:var(--lamplight)}
.app-sidebar .nav-form{margin-top:auto}
.app-sidebar .nav-button{width:100%;justify-content:flex-start}
.authenticated .page-back{display:none}
.dashboard-page .app-wrap{width:100%;margin:0;padding:0;max-width:none}
.dashboard-shell{min-height:100vh}
.dashboard-toolbar{
  position:sticky;
  top:0;
  z-index:40;
  min-height:68px;
  display:flex;
  align-items:center;
  gap:18px;
  padding:10px 30px;
  border-bottom:1px solid var(--line);
  background:#10131fee;
  backdrop-filter:blur(14px);
}
.dashboard-student-tabs{display:flex;gap:5px;min-width:0;overflow-x:auto;scrollbar-width:none}
.dashboard-student-tabs::-webkit-scrollbar{display:none}
.dashboard-student-tabs button{
  min-height:36px;
  padding:0 14px;
  border:1px solid var(--line);
  border-radius:8px;
  background:transparent;
  color:var(--dim);
  white-space:nowrap;
  font-size:.78rem;
  font-weight:650;
}
.dashboard-student-tabs button.active{border-color:#59627c;background:var(--dusk-2);color:var(--moon)}
.dashboard-toolbar-right{display:flex;align-items:center;gap:18px;margin-left:auto;flex:none}
.dashboard-source-mini{color:var(--dim);font-size:.72rem;white-space:nowrap}
.dashboard-source-mini i,.dashboard-verification i{
  display:inline-block;
  width:7px;
  height:7px;
  margin-right:7px;
  border-radius:50%;
  background:var(--attention);
}
.source-mini-verified i,.source-card-verified i{background:var(--settled);box-shadow:0 0 12px #7FC8A966}
.surface-control{display:flex;align-items:center;gap:8px;padding:6px 9px;border:1px solid var(--line);border-radius:999px;background:#0c101b}
.surface-label{color:var(--dim);font-size:.68rem;font-weight:700}
.surface-label.active{color:var(--moon)}
.surface-switch{position:relative;width:44px;height:24px;padding:0;border:0;border-radius:999px;background:#30384f}
.surface-switch span{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:var(--moon);box-shadow:0 2px 7px #0008;transition:transform .2s ease,background .2s ease}
.surface-switch[aria-checked="true"]{background:#d3ad62}
.surface-switch[aria-checked="true"] span{transform:translateX(20px);background:#fff9e9}
.dashboard-content{width:min(1220px,calc(100% - 52px));margin:0 auto;padding:38px 0 72px}
.dashboard-heading{display:flex;justify-content:space-between;align-items:flex-end;gap:28px;margin-bottom:25px}
.dashboard-heading h1{max-width:720px;margin:7px 0 0;font-size:clamp(2.5rem,4.8vw,3.8rem);line-height:1.01;letter-spacing:-.04em}
.dashboard-heading h1 em{color:var(--lamplight);font-style:normal;font-weight:500}
.dashboard-verification{min-width:285px;max-width:340px;padding:13px 0;border-top:1px solid var(--attention);border-bottom:1px solid var(--line)}
.dashboard-verification strong{display:block;font-size:.78rem}
.dashboard-verification span,.dashboard-verification small{display:block;color:var(--dim);font-size:.67rem;line-height:1.5}
.dashboard-verification a{display:inline-block;margin-top:6px;font-size:.72rem;font-weight:700}
.source-card-verified{border-top-color:var(--settled)}
/* No box: this was a bordered slab stacked on the week panel's bordered slab in
   near-identical colours, which is why the regions all read the same. The big
   display numbers and their two accent colours carry it without a container. */
.dashboard-summary{display:grid;grid-template-columns:repeat(4,1fr);margin-bottom:14px;border:0;border-radius:0;background:transparent}
.summary-cell{padding:2px 17px}
/* Aligns the first number to the same x as the panel borders below it. */
.summary-cell:first-child{padding-left:0}
.summary-cell+.summary-cell{border-left:1px solid var(--line)}
.summary-cell strong{display:block;font-family:var(--display);font-size:1.55rem;font-weight:400;line-height:1.05}
.summary-cell span{color:var(--dim);font-size:.68rem}
.summary-action strong{color:var(--attention)}
.summary-done strong{color:var(--settled)}
/* Asymmetric on purpose. The row filters .dashboard-grid, so it stays close to
   it (13px) and far from the week panel it does not control (34px). Equal space
   on both sides is what made a bare control row read as the panel's footer. */
.dashboard-filters{display:flex;align-items:center;gap:6px;margin-top:34px;margin-bottom:13px;overflow-x:auto;scrollbar-width:none}
.dashboard-filters::-webkit-scrollbar{display:none}
.dashboard-filters button{min-height:35px;padding:0 12px;border:1px solid var(--line);border-radius:999px;background:transparent;color:var(--dim);white-space:nowrap;font-size:.72rem;font-weight:700}
.dashboard-filters button.active{border-color:var(--moon);background:var(--moon);color:var(--night)}
.dashboard-filters small{margin-left:auto;color:var(--dim);font-size:.67rem;white-space:nowrap}
.dashboard-grid{display:grid;gap:18px}
.dashboard-student-block{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(310px,.75fr);gap:18px;align-items:start}
.dashboard-student-block[hidden],.dashboard-group[hidden],.activity-row[hidden]{display:none!important}
.dashboard-panel{border:1px solid var(--line);border-radius:13px;background:var(--dusk);overflow:hidden}
.dashboard-panel-heading{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;padding:20px 21px 17px;border-bottom:1px solid var(--line)}
.dashboard-panel-heading.compact{align-items:center}
/* A support panel was speaking at the main content's volume: this h2 used the
   same clamp() as each student's brief heading, so the eye could not rank them.
   Two classes to outgun the clamp rule's specificity. */
.week-panel .dashboard-panel-heading{padding:14px 21px 12px}
.week-panel .dashboard-panel-heading h2{font-size:1rem;font-weight:700;letter-spacing:0}
.week-panel .week-strip{padding-bottom:8px}
/* The week panel now follows the student grid, so it needs the same zone break
   above it that the filter row gets -- .dashboard-panel carries no margin of
   its own and it would otherwise butt against the last brief. */
.week-panel{margin-top:34px}
.dashboard-panel-heading h2{margin:0;font-size:clamp(1.35rem,2.4vw,1.65rem)}
.dashboard-panel-heading span,.dashboard-panel-heading p{display:block;margin:4px 0 0;color:var(--dim);font-size:.67rem}
.dashboard-panel-heading button,.dashboard-panel-heading a{padding:4px 0;border:0;background:transparent;color:var(--lamplight);font-size:.67rem;font-weight:700;white-space:nowrap}
.dashboard-brief{border-radius:22px 22px 12px 12px;background:linear-gradient(158deg,var(--dusk-2),#171d2e 64%,#121624);box-shadow:0 30px 80px -58px #000}
.dashboard-queue{padding:3px 21px 8px}
.dashboard-group{position:relative;padding:21px 0 6px 21px}
.dashboard-group+.dashboard-group{border-top:1px solid var(--line)}
.dashboard-group>h3{position:relative;margin:0 0 6px;color:var(--dim);font-family:var(--body);font-size:.62rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase}
.dashboard-group>h3 span{color:inherit}
.dashboard-group>h3::before{content:"";position:absolute;left:-21px;top:3px;width:8px;height:8px;border:2px solid var(--dusk-2);border-radius:50%;background:var(--attention);box-shadow:0 0 0 1px var(--attention)}
.group-watch>h3::before{background:var(--lamplight);box-shadow:0 0 0 1px #ab791a}
.group-done>h3::before{background:var(--settled);box-shadow:0 0 0 1px #4e9678}
.course-group{border-top:1px solid #ffffff0b}
.course-group:first-of-type{border-top:0}
.course-group>summary{display:flex;align-items:center;gap:8px;padding:9px 0;cursor:pointer;list-style:none;color:var(--dim);font-size:.72rem}
.course-group>summary::-webkit-details-marker{display:none}
.course-group>summary::before{content:"";flex:none;width:0;height:0;border-left:4px solid currentColor;border-top:3.5px solid transparent;border-bottom:3.5px solid transparent;transition:transform .12s ease}
.course-group[open]>summary::before{transform:rotate(90deg)}
.course-group>summary:hover{color:var(--ink)}
.course-group-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.course-group-count{flex:none;padding:1px 7px;border-radius:9px;background:#ffffff0f;font-size:.64rem;font-variant-numeric:tabular-nums}
.course-group .dashboard-item{padding-left:12px}
.dashboard-item{position:relative;display:grid;grid-template-columns:minmax(0,1fr) 104px 94px;column-gap:12px;row-gap:2px;align-items:center;min-height:67px;padding:12px 0;border-bottom:1px solid #ffffff0b}
.dashboard-item-copy{grid-column:1;grid-row:1}
.dashboard-item time{grid-column:1;grid-row:2}
.dashboard-item .dashboard-points{grid-column:2;grid-row:1/3;align-self:center}
.dashboard-item .why-button{grid-column:3;grid-row:1/3;align-self:center}
.dashboard-item .dashboard-reason{grid-column:1/-1;grid-row:3}
.dashboard-item:last-child{border-bottom:0}
.dashboard-item h4{margin:0 0 3px;font-size:.95rem;line-height:1.3}
.dashboard-item p{margin:0;color:var(--dim);font-size:.79rem;line-height:1.4}
.dashboard-item time{color:var(--dim);font-size:.79rem}
.dashboard-item button{min-height:34px;padding:0 10px;border:1px solid var(--dim);border-radius:8px;background:transparent;color:var(--moon);font-size:.75rem;font-weight:650;white-space:nowrap}
.dashboard-item button:hover{border-color:var(--lamplight);color:var(--lamplight)}
.dashboard-reason{grid-column:1/-1;margin:-2px 0 5px!important;padding:8px 10px;border-radius:6px;background:#0f1422;color:#b4bbcc!important}
.dashboard-reason{font-size:.8rem;line-height:1.5}
.dashboard-reason{transition:opacity .12s ease}
.dashboard-empty{padding:28px 0}
.dashboard-filter-empty{margin:18px 21px 24px;padding:22px;border:1px dashed var(--line);border-radius:9px;text-align:center}
.dashboard-filter-empty h3{margin:0 0 4px;font-size:.88rem}
.dashboard-filter-empty p{margin:0;color:var(--dim);font-size:.7rem}
.dashboard-empty.compact{padding:22px}
.dashboard-empty h3{margin-bottom:4px}
.dashboard-empty p{margin:0;color:var(--dim);font-size:.78rem}
.dashboard-rail{display:grid;gap:16px}
.course-list{display:grid}
.course-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:14px;padding:15px 19px;border-bottom:1px solid #ffffff0b}
.course-row:last-child{border-bottom:0}
.course-row h3{margin:0 0 2px;font-size:.78rem}
.course-row p{margin:0;color:var(--dim);font-size:.65rem}
.course-row>strong{font-family:var(--display);font-size:1.4rem;font-weight:400;text-align:right}
.course-row>strong span{color:var(--dim);font-family:var(--body);font-size:.67rem}
.course-empty{padding:22px;color:var(--dim);font-size:.75rem}
.dashboard-confidence{padding:16px 18px;border:1px solid #E8927C44;border-radius:12px;background:#2c1d25}
.dashboard-confidence strong{display:block;margin-bottom:4px;color:#ffd6cd;font-size:.77rem}
.dashboard-confidence p{margin:0;color:#d4aaa0;font-size:.67rem}
.source-confidence-verified{border-color:#7FC8A944;background:#15271f}
.source-confidence-verified strong{color:#d6f2e5}
.source-confidence-verified p{color:#9fc8b6}
.dashboard-activity{grid-column:1/-1}
.activity-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.activity-row{display:grid;grid-template-columns:74px 1fr;gap:12px;padding:16px 20px}
.activity-row+.activity-row{border-left:1px solid var(--line)}
.activity-row time{color:var(--dim);font-family:var(--mono);font-size:.59rem}
.activity-row strong{font-size:.73rem}
.activity-row p{margin:2px 0 0;color:var(--dim);font-size:.65rem}
.dashboard-onboarding{padding:34px;grid-column:1/-1}
.dashboard-onboarding p{max-width:42rem;color:var(--dim)}
/* Embedded billing */
.billing-page .app-wrap{width:min(100%,calc(1160px + 48px))}
.checkout-heading{max-width:760px;margin:0 auto 34px;text-align:center}
.checkout-heading .checkout-back{display:inline-block;margin-bottom:26px;color:var(--dim);font-size:.82rem;font-weight:600}
.checkout-heading .checkout-back:hover{color:var(--moon)}
.checkout-heading h1{margin-bottom:.8rem}
.checkout-heading h1 em{font-style:normal}
.checkout-heading .lede{max-width:630px;margin-inline:auto;color:var(--dim)}
.checkout-layout{display:grid;grid-template-columns:minmax(280px,360px) minmax(0,1fr);gap:22px;align-items:start}
.checkout-summary{position:sticky;top:88px;overflow:hidden;border:1px solid #F5B84A45;border-radius:var(--radius);background:linear-gradient(155deg,#25283a,#181d2d 72%);box-shadow:0 24px 70px -50px #000}
.checkout-summary-top{padding:29px 28px 23px;border-bottom:1px solid var(--line)}
.checkout-summary-top h2{margin-bottom:1.1rem;font-size:2rem}
.checkout-price{display:flex;align-items:baseline;gap:10px;margin-bottom:2px}
.checkout-price span{color:var(--moon);font-family:var(--display);font-size:3.5rem;font-weight:500;line-height:1}
.checkout-price small{color:var(--dim);font-size:.78rem;font-weight:600}
.checkout-value{margin:8px 0 0;color:var(--dim);font-size:.8rem}
.checkout-benefits{display:grid;gap:14px;margin:0;padding:24px 28px;list-style:none}
.checkout-benefits li{display:grid;grid-template-columns:19px 1fr;gap:8px;color:#d7dbea;font-size:.82rem;line-height:1.45}
.checkout-benefits li span{color:var(--settled);font-weight:800}
.checkout-trial-note{margin:0 18px 18px;padding:17px 18px;border:1px solid #7FC8A93d;border-radius:10px;background:#142821}
.checkout-trial-note strong{display:block;margin-bottom:5px;color:#d6f2e5;font-size:.78rem}
.checkout-trial-note p{margin:0;color:#9fc8b6;font-size:.72rem;line-height:1.5}
.checkout-payment{min-width:0;padding:24px;background:#171c2b}
.checkout-payment-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;padding-bottom:14px;border-bottom:1px solid var(--line)}
.checkout-payment-heading h2{margin:0}
.stripe-secure-mark{flex:none;padding:6px 9px;border:1px solid var(--line);border-radius:999px;color:var(--dim);font-size:.66rem;font-weight:700}
.stripe-secure-mark span{margin-right:3px;color:var(--settled)}
.checkout-privacy{margin:12px 0 0;color:var(--dim);font-size:.74rem;line-height:1.45}
.payment-element-shell{margin-top:16px}
.checkout-loading{margin:9px 0 0;color:var(--dim);font-size:.74rem;line-height:1.4}
.checkout-loading[hidden]{display:none}
.checkout-error{padding:18px;border:1px solid #E8927C70;border-radius:10px;background:#3a242b;color:#ffd7ce}
.checkout-submit{width:100%;min-height:48px;margin-top:14px;border-radius:10px}
.checkout-submit:disabled{cursor:not-allowed;opacity:.55;transform:none;box-shadow:none}
.checkout-submit.is-processing{cursor:wait}
.checkout-fallback{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px;margin-top:18px;padding-top:15px;border-top:1px solid var(--line);color:var(--dim);font-size:.72rem}
.checkout-fallback p{margin:0}
.checkout-fallback form{margin:0}
.text-button{padding:0;border:0;background:transparent;color:var(--lamplight);font-size:inherit;font-weight:700}
.text-button:hover{text-decoration:underline}
.checkout-assurances{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;margin-top:22px;overflow:hidden;border:1px solid var(--line);border-radius:10px;background:var(--line)}
.checkout-assurances span{padding:15px 17px;background:#151a28;color:var(--dim);font-size:.68rem;line-height:1.45}
.checkout-assurances strong{display:block;margin-bottom:2px;color:var(--moon);font-size:.72rem}

/* C's warm paper perspective changes only the main brief surface. */
.paper-surface .dashboard-brief{border-color:#d4d0c4;background:#ece8dc;color:#1a1d25;box-shadow:0 28px 70px -50px #000}
.paper-surface .dashboard-brief .dashboard-panel-heading{border-color:#cfcbc0}
.paper-surface .dashboard-brief .dashboard-panel-heading span,
.paper-surface .dashboard-brief .dashboard-panel-heading p,
.paper-surface .dashboard-brief .dashboard-item p,
.paper-surface .dashboard-brief .dashboard-item time,
.paper-surface .dashboard-brief .dashboard-group>h3{color:#696c76}
.paper-surface .dashboard-brief .dashboard-group+.dashboard-group,
.paper-surface .dashboard-brief .dashboard-item{border-color:#1a1d2518}
.paper-surface .dashboard-brief .dashboard-group>h3::before{border-color:#ece8dc}
.paper-surface .dashboard-brief .dashboard-item button{border-color:#bdb9ae;background:#f4f1e8;color:#1a1d25}
.paper-surface .dashboard-brief .dashboard-item button:hover{border-color:#7e796d;color:#1a1d25}
.paper-surface .dashboard-brief .dashboard-reason{background:#dedacd;color:#535762!important}

@media (max-width:980px){
  /* Below this width the sidebar gives way to the fixed bottom bar, and the
     top bar keeps behaving exactly as it does on the marketing pages. */
  .authenticated{display:flex;padding-bottom:72px}
  .app-sidebar{display:none}
  .dashboard-page .app-wrap{width:100%;margin:0}
  .authenticated .page-back{display:inline-block}
  .dashboard-toolbar{position:static;flex-wrap:wrap;padding:9px 16px}
  .dashboard-student-tabs{order:2;width:100%;padding-top:9px;border-top:1px solid var(--line)}
  .dashboard-toolbar-right{margin-left:0;width:100%;justify-content:space-between}
  .dashboard-content{width:calc(100% - 30px);padding-top:28px}
  .dashboard-heading{display:block}
  .dashboard-verification{margin-top:20px}
  .dashboard-student-block{grid-template-columns:1fr}
  .activity-list{grid-template-columns:1fr}
  .activity-row+.activity-row{border-left:0;border-top:1px solid var(--line)}
  /* bottom sits above the home indicator. Without the safe-area inset this bar
     renders underneath it on any iPhone X-or-later and gesture-nav Android,
     which is why it read as "barely visible". */
  .app-mobile-nav{position:fixed;z-index:60;left:10px;right:10px;bottom:calc(9px + env(safe-area-inset-bottom,0px));display:flex;justify-content:space-around;padding:7px;border:1px solid var(--line);border-radius:13px;background:#121724ed;backdrop-filter:blur(12px);box-shadow:0 16px 44px #0008}
  /* 44px minimum touch target (Apple HIG and WCAG 2.5.5); the old 65x30 was under it. */
  .app-mobile-nav a{display:flex;align-items:center;justify-content:center;min-width:68px;min-height:44px;padding:6px 8px;border-radius:9px;color:var(--dim);text-align:center;font-size:.72rem;font-weight:650;text-decoration:none}
  /* Active state carries a background, not only a hue change: colour alone is
     easy to miss at this size and fails WCAG 1.4.1 Use of Color. */
  .app-mobile-nav a.active,
  .app-mobile-nav a[aria-current="page"]{background:#20273a;color:var(--lamplight);box-shadow:inset 0 0 0 1px #2f3854}
  .app-mobile-nav a:active{background:#1a2032}
  .authenticated{padding-bottom:calc(72px + env(safe-area-inset-bottom,0px))}
}
@media (max-width:620px){
  .dashboard-content{width:calc(100% - 24px);padding-top:23px}
  .dashboard-source-mini{display:none}
  .dashboard-heading h1{font-size:2.45rem}
  .dashboard-summary{grid-template-columns:repeat(2,1fr);row-gap:12px}
  /* The box is gone, so these would paint stray rules floating in space, and
     cell 3 -- leftmost in the second row -- would keep an indent cell 1 lacks. */
  .summary-cell:nth-child(3){border-left:0;border-top:0;padding-left:0}
  .summary-cell:nth-child(4){border-top:0}
  .dashboard-filters{margin-top:26px}
  .dashboard-filters small{display:none}
  .dashboard-panel-heading{padding:18px 16px 15px}
  .week-strip li{padding:.35rem 16px}
  .dashboard-queue{padding-inline:16px}
  .dashboard-item{grid-template-columns:minmax(0,1fr) auto}
  .dashboard-item-copy{grid-column:1;grid-row:1}
  .dashboard-item time{grid-column:1;grid-row:2}
  .dashboard-item .dashboard-points{grid-column:1;grid-row:3;justify-self:start}
  .dashboard-item .why-button{grid-column:2;grid-row:1/4;width:76px}
  .dashboard-item .dashboard-reason{grid-column:1/-1;grid-row:4}
  .activity-row{padding-inline:16px}
}

@media (max-width:880px){
  .checkout-layout{grid-template-columns:1fr}
  .checkout-summary{position:static}
  .checkout-benefits{grid-template-columns:repeat(2,minmax(0,1fr))}
  .checkout-assurances{grid-template-columns:1fr}
}

@media (max-width:620px){
  .billing-page .app-wrap{padding-top:34px;padding-inline:16px}
  .checkout-heading{margin-bottom:24px;text-align:left}
  .checkout-heading .checkout-back{margin-bottom:22px}
  .checkout-heading h1{font-size:2.45rem}
  .checkout-summary-top,.checkout-benefits{padding-inline:21px}
  .checkout-benefits{grid-template-columns:1fr}
  .checkout-payment{padding:18px 16px}
  .checkout-payment-heading{display:block}
  .stripe-secure-mark{display:inline-block;margin-top:9px}
  .checkout-fallback{display:block}
  .checkout-fallback form{margin-top:2px}
}
@media (prefers-reduced-motion:reduce){
  .surface-switch span{transition:none}
}


/* Staff operations center */
.operations-page .app-wrap{width:min(1180px,calc(100% - 260px));margin-left:230px;padding-top:38px}
.operations-shell{display:grid;gap:22px;padding-bottom:48px}
.operations-tabs{display:flex;gap:6px;width:max-content;max-width:100%;padding:5px;border:1px solid var(--line);border-radius:12px;background:#111725;overflow-x:auto}
.operations-tabs a{display:inline-flex;align-items:center;justify-content:center;min-height:38px;padding:0 18px;border-radius:8px;color:var(--dim);font-size:.76rem;font-weight:750;text-decoration:none;white-space:nowrap}
.operations-tabs a:hover,.operations-tabs a:focus-visible{color:var(--paper);background:#ffffff0b}
.operations-tabs a.active{color:#10131f;background:var(--lamplight)}
.operations-detail-header .operations-read-only{display:inline-flex;margin-right:7px;padding:3px 8px;border:1px solid #76cf9f66;border-radius:999px;color:#76cf9f;font-size:.66rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase}
.customer-account-link{display:grid;gap:3px;color:var(--paper);text-decoration:none}
.customer-account-link strong{color:var(--paper)}
.customer-account-link span{color:var(--lamplight);font-size:.72rem;overflow-wrap:anywhere}
.customer-account-link:hover strong,.customer-account-link:focus-visible strong{text-decoration:underline;text-decoration-color:var(--lamplight);text-underline-offset:3px}
.customer-settings-link{display:inline-flex;margin-top:9px;font-size:.68rem;font-weight:750}
.customer-settings-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.customer-settings-grid .operations-section{min-width:0}
.customer-settings-list{display:grid;gap:0;margin:0}
.customer-settings-list>div{display:grid;grid-template-columns:minmax(120px,.75fr) minmax(0,1.25fr);gap:14px;padding:10px 0;border-bottom:1px solid #ffffff0d}
.customer-settings-list>div:last-child{border-bottom:0}
.customer-settings-list dt{color:var(--dim);font-size:.68rem}
.customer-settings-list dd{margin:0;color:var(--paper);font-size:.74rem;font-weight:650;overflow-wrap:anywhere}
.customer-settings-list.compact{margin-top:9px}
.customer-user-list{display:grid;gap:10px}
.customer-user-list>article{padding:14px;border:1px solid #ffffff12;border-radius:10px;background:#171d2d}
.customer-user-list>article>span{display:block;margin-top:3px;color:var(--lamplight);font-size:.72rem;overflow-wrap:anywhere}
.customer-activity-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.customer-activity-grid>div{padding:15px;border:1px solid #ffffff12;border-radius:10px;background:#171d2d}
.customer-activity-grid h3{margin:0 0 10px;font-size:.84rem}
.customer-activity-grid p{color:var(--dim);font-size:.7rem;line-height:1.55}
.ticket-conversation{padding:20px}
.ticket-message{padding:.7rem;border-left:3px solid var(--line);background:var(--dusk);white-space:pre-wrap;overflow-wrap:anywhere}
.ticket-update-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:16px}
.ticket-update-form label:last-of-type,.ticket-update-form .fine-print{grid-column:1/-1}
.ticket-update-form textarea{display:block;width:100%;min-height:100px;margin-top:5px}
@media (max-width:620px){.operations-page .app-wrap{width:100%;margin:0;padding:24px 16px 96px}.ticket-update-form{grid-template-columns:1fr}.ticket-update-form button{width:100%}}
.operations-header,.operations-section{border:1px solid var(--line);border-radius:16px;background:#111725;box-shadow:0 20px 60px #0003}
.operations-header{padding:28px;background:radial-gradient(circle at 92% 8%,#f5b84a22,transparent 32%),linear-gradient(145deg,#161d2d,#101522)}
.operations-header h1{margin:3px 0 8px;font-size:clamp(2.25rem,4vw,3.75rem)}
.operations-header>p:not(.eyebrow){max-width:42rem;margin:0;color:var(--dim)}
.operations-status-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:20px;color:var(--dim);font-size:.74rem}
.operations-status{display:inline-flex;align-items:center;min-height:29px;padding:0 11px;border:1px solid currentColor;border-radius:999px;font-size:.67rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.operations-status.status-healthy{color:#76cf9f}.operations-status.status-degraded,.operations-status.status-stale{color:var(--lamplight)}.operations-status.status-down,.operations-status.status-unavailable{color:#ef8b89}
.operations-section{padding:24px}
.operations-section-heading{display:grid;gap:3px;margin-bottom:17px}
.operations-section-heading h2{margin:0;font-size:1.35rem}
.operations-section-heading>p:last-child{max-width:48rem;margin:4px 0 0;color:var(--dim);font-size:.75rem}
.operations-host-usage,.operations-metric-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}
.operations-host-usage>article,.operations-metric{display:grid;gap:4px;min-height:94px;padding:15px;border:1px solid #ffffff13;border-radius:11px;background:#171d2d}
.operations-host-usage>article span,.operations-metric span{color:var(--dim);font-size:.68rem}
.operations-host-usage>article strong,.operations-metric strong{font-family:var(--display);font-size:1.65rem;font-weight:500;color:var(--paper)}
.operations-component-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;margin-top:10px}
.operations-component{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:9px 12px;align-items:start;min-height:92px;padding:14px;border:1px solid #ffffff12;border-radius:10px;background:#121827}
.operations-component>div{display:flex;align-items:flex-start;gap:8px;min-width:0}
.operations-component>div strong{color:var(--paper);font-size:.76rem;line-height:1.4}
.operations-dot{flex:0 0 auto;width:8px;height:8px;margin-top:5px;border-radius:50%;background:var(--dim)}
.operations-component-status{font-size:.65rem;font-weight:750;text-transform:capitalize}
.operations-component.status-healthy .operations-dot{background:#76cf9f}.operations-component.status-healthy .operations-component-status{color:#76cf9f}
.operations-component.status-degraded .operations-dot,.operations-component.status-not_configured .operations-dot{background:var(--lamplight)}.operations-component.status-degraded .operations-component-status,.operations-component.status-not_configured .operations-component-status{color:var(--lamplight)}
.operations-component.status-down .operations-dot{background:#ef8b89}.operations-component.status-down .operations-component-status{color:#ef8b89}
.operations-component dl{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:6px 14px;margin:0;color:var(--dim);font-size:.61rem}
.operations-component dl:empty{display:none}
.operations-component dl>div{display:flex;gap:5px}.operations-component dt,.operations-component dd{margin:0}.operations-component dd{color:var(--paper);font-weight:700}
.operations-backup-strip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}
.operations-backup-strip>div{display:grid;gap:4px;padding:11px 13px;border:1px solid #ffffff10;border-radius:9px;background:#101624}
.operations-backup-strip span{color:var(--dim);font-size:.65rem}.operations-backup-strip strong{font-size:.76rem}
.operations-empty{padding:18px;border:1px solid currentColor;border-radius:11px;background:#171b28}
.operations-empty p{margin:5px 0 0;color:var(--dim);font-size:.72rem}
.operations-flow-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.operations-flow-grid>article{padding:16px;border:1px solid #ffffff12;border-radius:11px;background:#171d2d}
.operations-flow-grid h3{margin:0 0 12px;font-size:.82rem}
.operations-flow-grid dl{display:grid;gap:7px;margin:0}
.operations-flow-grid dl>div{display:flex;justify-content:space-between;gap:12px;padding-bottom:7px;border-bottom:1px solid #ffffff0c}
.operations-flow-grid dt{color:var(--dim);font-size:.67rem}.operations-flow-grid dd{margin:0;font-weight:800;font-size:.72rem}
.nav-operations::before{content:"◉";margin-right:7px;color:var(--lamplight)}
@media (max-width:1050px){
  .operations-page .app-wrap{width:calc(100% - 220px);margin-left:210px;padding-inline:16px}
  .operations-host-usage,.operations-metric-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .operations-component-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:760px){
  .operations-page.authenticated{padding-bottom:0}
  .operations-page .app-wrap{width:100%;margin:0;padding:25px 14px 42px}
  .operations-tabs{width:100%}
  .operations-tabs a{flex:1}
  .operations-header,.operations-section{padding:18px;border-radius:13px}
  .operations-component-grid,.operations-flow-grid,.customer-settings-grid,.customer-activity-grid{grid-template-columns:1fr}
  .operations-backup-strip{grid-template-columns:1fr}
  .operations-page .app-mobile-nav{position:static;left:auto;right:auto;bottom:auto;justify-content:space-around;margin:0 14px 18px}
}
@media (max-width:480px){
  .operations-host-usage,.operations-metric-grid{grid-template-columns:1fr 1fr}
  .operations-host-usage>article,.operations-metric{min-height:82px;padding:12px}
  .operations-component{grid-template-columns:1fr}
  .operations-component-status{grid-column:1;justify-self:start}
  .customer-settings-list>div{grid-template-columns:1fr;gap:4px}
}

.operations-filters{display:grid;grid-template-columns:2fr repeat(2,minmax(160px,1fr));gap:14px;align-items:end}
.operations-filter-field{display:grid;gap:6px;min-width:0}
.operations-filter-search{grid-column:span 2}
.operations-filters label{font-size:.76rem;color:var(--dim)}
.operations-filters input,.operations-filters select,.operations-filters textarea,textarea{width:100%;min-height:48px;padding:.8rem 1rem;border:1px solid var(--line);border-radius:10px;background:var(--night);color:var(--moon);font:inherit}
.operations-filters textarea,textarea{min-height:120px;resize:vertical}
.customer-table-hint{display:none}
.customer-table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:12px}
.customer-table{width:100%;min-width:760px;border-collapse:collapse;font-size:.78rem}
.customer-table th,.customer-table td{padding:12px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}
.customer-table th{color:var(--dim);font-size:.68rem;text-transform:uppercase}
.ticket-row{display:grid;gap:2px;padding:12px 0;border-top:1px solid var(--line)}
.ticket-row span{color:var(--dim);font-size:.8rem}
@media (max-width:760px){.operations-filters{grid-template-columns:1fr}.operations-filter-search{grid-column:auto}.customer-table-hint{display:block;margin:-8px 0 2px;color:var(--dim);font-size:.76rem}.customer-table{min-width:760px}}

/* --- the class list ---------------------------------------------------------
   Was a five-column table. Every row carried a full sentence in two of those
   columns, so the page read as prose with numbers buried in it, and on a phone the
   whole thing scrolled sideways. Now each course is a <details>: figures in the
   summary, explanations and the assignment list inside.

   Built narrow-first. The summary stacks on a phone and becomes a row from 640px,
   so nothing ever scrolls sideways and there is no second layout to keep in step.

   PALETTE NOTE, learned the hard way: this stylesheet's variables are --moon,
   --dim, --line, --attention, --night, --dusk, --dusk-2, --lamplight. The first
   draft of this block invented --muted, --hairline, --text, --alarm-bed and
   --alarm-ink, none of which exist, so every declaration using them without a
   fallback was silently dropped and the text simply inherited. It looked almost
   right, which is why it survived a screenshot. */
.courses-shell{display:grid;gap:1.1rem}
.courses-head h1{margin:0 0 .25rem}
.courses-sub{margin:0;color:var(--dim);max-width:52ch}
.courses-note{margin:0;color:var(--dim);font-size:.88rem;max-width:64ch}
.courses-empty{color:var(--dim)}
.courses-alert{margin:0;padding:.7rem .85rem;border-radius:.5rem;background:var(--dusk);border:1px solid var(--lamplight);font-size:.9rem;line-height:1.45}
.courses-alert strong{display:block;margin-bottom:.15rem}

.course-list{list-style:none;margin:0;padding:0;display:grid;gap:.5rem}
/* Grid items refuse to shrink below their content's minimum by default, so one wide
   child propagates all the way up and widens the page. Insurance alongside the tbody
   fix above -- the chain, not one link, is what keeps the page at viewport width. */
.course-list>li{min-width:0}
.courses-shell{min-width:0}

.course{border:1px solid var(--line);border-radius:.6rem;background:var(--dusk);overflow:hidden}
.course[open]{border-color:color-mix(in srgb,var(--lamplight) 42%,var(--line))}
.course.is-muted{opacity:.72}

.course>summary{display:flex;flex-direction:column;gap:.55rem;padding:.8rem .9rem;cursor:pointer;list-style:none}
.course>summary::-webkit-details-marker{display:none}
.course>summary:focus-visible{outline:2px solid var(--lamplight);outline-offset:-2px}
.course>summary:hover{background:var(--dusk-2)}

.course-name{display:flex;flex-direction:column;gap:.1rem;min-width:0}
.course-title{font-weight:600;line-height:1.3;color:var(--moon)}
.course-sub{color:var(--dim);font-size:.82rem}
.course .tag{font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;color:var(--dim)}

.course-stats{display:flex;flex-wrap:wrap;align-items:baseline;gap:.35rem 1.1rem}
.stat{display:flex;flex-direction:column;gap:.05rem;min-width:0}
.stat b{font-variant-numeric:tabular-nums;font-weight:600;line-height:1.2;color:var(--moon)}
.stat b.figure{font-size:1.15rem}
.stat small{color:var(--dim);font-size:.72rem;text-transform:uppercase;letter-spacing:.03em}
.is-absent{color:var(--dim);font-weight:400}

.pill{align-self:center;font-size:.78rem;font-variant-numeric:tabular-nums;padding:.16rem .5rem;border-radius:999px;background:var(--dusk-2);color:var(--moon);white-space:nowrap}
.pill-missing{background:color-mix(in srgb,var(--attention) 26%,var(--night));color:var(--attention)}
.pill-unsure{background:transparent;border:1px dashed var(--line);color:var(--dim)}

.course-detail{padding:.75rem .9rem .85rem;display:grid;gap:.6rem;border-top:1px solid var(--line)}
.detail-note{margin:0;color:var(--dim);font-size:.86rem;line-height:1.45;max-width:60ch}
.detail-next{color:var(--moon)}

/* The assignment list. Both of these override GLOBAL rules that would otherwise ruin
   it: `table{display:block;overflow-x:auto}` breaks column alignment outright, and
   `th{color:var(--dim);font-size:.76rem;text-transform:uppercase}` turned every
   assignment title into small muted capitals -- which is exactly how the first
   render looked, and why the two columns that matter appeared blank. */
.assignments{display:table;width:100%;border-collapse:collapse;font-size:.88rem;overflow:visible}
/* The global `tbody{min-width:620px}` (ops tables) reaches in here and forces every
   class card to ~750px minimum -- which laid the WHOLE PAGE out at 768px inside a 390px
   phone and clipped the right third of it. Measured, not guessed: document.scrollWidth
   768 vs viewport 390 before this rule, 390 after. */
.assignments tbody{display:table-row-group;width:auto;min-width:0}
.assignments thead{display:table-header-group}
.assignments tr{display:table-row}
/* Long unbroken titles ("Exponent/Algebra/Factoring review") set the table's minimum
   width; let them break anywhere so the card can always shrink to the phone. */
.assignments tbody th{overflow-wrap:anywhere}
.assignments th,.assignments td{padding:.4rem .5rem;text-align:left;vertical-align:top;border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent)}
.assignments thead th{color:var(--dim);font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;font-weight:600}
.assignments tbody th{color:var(--moon);font-size:.88rem;font-weight:400;text-transform:none;letter-spacing:0;line-height:1.35}
.assignments tbody tr:last-child th,.assignments tbody tr:last-child td{border-bottom:0}
.assignments .col-due{white-space:nowrap;color:var(--dim);width:1%}
.assignments .col-score{text-align:right;white-space:nowrap;width:1%;font-variant-numeric:tabular-nums;color:var(--moon)}
.assignments .score-note{display:block;color:var(--dim);font-size:.74rem;white-space:normal;max-width:18ch;margin-left:auto}
.assignments tr.is-missing th{color:var(--attention)}

.stat-quiet small{text-transform:none;letter-spacing:0;font-size:.82rem}

@media (min-width:640px){
  .course>summary{flex-direction:row;align-items:center;justify-content:space-between;gap:1.2rem}
  .course-name{flex:1 1 auto;min-width:0}
  /* Fixed tracks with each figure PLACED BY NAME. Two of the four are optional, so a plain
     right-aligned flex row -- or even a grid relying on source order -- left STANDING and
     POINTS MARKED at a different x on every row. Explicit grid-column is what makes the
     columns line up whether or not a posted grade or a pill is present. */
  .course-stats{flex:0 0 auto;display:grid;grid-template-columns:6rem 6rem 9rem 8rem;align-items:center;gap:0 1rem}
  .stat-posted{grid-column:1}
  .stat-standing{grid-column:2}
  .stat-points{grid-column:3}
  .pill{grid-column:4;justify-self:end}
  /* The "nothing to report" line has no figures to align, so it spans the lot and stays
     right-aligned with them. */
  .stat-quiet{grid-column:1 / 4;text-align:right}
  .stat{align-items:flex-end;text-align:right}
}

/* --- dashboard: this-week strip + standing chips ------------------------------- */
.week-strip{list-style:none;margin:0;padding:0;display:grid;gap:.35rem}
/* Inset to the same 21px as .dashboard-panel-heading. The text sat hard against
   the panel border while the heading above it was inset, so the rows read as
   overflowing their own card. The padding is on the row, not the list, so the
   divider still runs the full width like the heading's border does. */
.week-strip li{display:flex;flex-wrap:wrap;gap:.25rem .8rem;align-items:baseline;padding:.35rem 21px;border-bottom:1px solid color-mix(in srgb,var(--line) 55%,transparent)}
.week-strip li:last-child{border-bottom:0}
.week-day{font-variant-numeric:tabular-nums;color:var(--moon);font-weight:600}
.week-courses{color:var(--dim);font-size:.85rem}
.standing-chip{margin:.3rem 0 0}
.standing-chip a{display:inline-block;white-space:nowrap;font-size:.8rem;font-variant-numeric:tabular-nums;padding:.14rem .55rem;border-radius:999px;background:var(--dusk-2);color:var(--moon);text-decoration:none;border:1px solid var(--line)}
.standing-chip a:hover{border-color:var(--lamplight)}


/* --- compact phone scale ---------------------------------------------------------
   Requested after comparing the true mobile rendering with the request-desktop one:
   the desktop layout shrunk to a phone read better than the mobile layout did. One
   knob, not per-page tweaks: nearly every font on the site is set in rem, so lowering
   the root size compacts every page the same way -- classes, dashboard, settings --
   keeping them unified. 17px body / 16px root becomes ~14px, roughly the density of
   the shrunk desktop view while staying honestly readable.

   Text inputs stay at 16px: below that, iOS Safari zooms the page on focus, which is
   worse than any font-size problem. */
@media (max-width:640px){
  html{font-size:14px}
  body{font-size:1rem}
  h1{font-size:1.9rem}
  input,select,textarea{font-size:16px}
  .wrap{padding-inline:16px}
  .stat b.figure{font-size:1.05rem}
}

/* Guided-connect walkthrough. The screenshots are 1440px captures; on any
   screen they scale down, never up, and the tall account-menu crop stays
   readable by capping to its natural width instead. */
.guide-step{margin:28px 0}
.guide-shot{display:block;max-width:100%;height:auto;margin-top:12px;border:1px solid var(--line);border-radius:10px;box-shadow:0 6px 22px rgba(10,16,32,.10)}
.guide-shot--tall{max-width:480px}

/* --- the operations wall ----------------------------------------------------
   A NOC view answers one question on sight: is anything wrong, and what. The
   verdict band carries the colour, the feed carries the specifics, and every
   reference panel below it is deliberately quieter than both. */
.noc-verdict{display:grid;gap:18px;padding:22px 24px;border:1px solid var(--line);border-radius:14px;background:#141a29}
.noc-verdict-headline{display:flex;align-items:center;gap:16px}
.noc-verdict-headline h1{margin:2px 0 0;font-size:1.5rem;line-height:1.1}
.noc-dot{flex:0 0 auto;width:14px;height:14px;border-radius:50%;background:var(--dim)}
.noc-ok{border-color:#76cf9f4d}
.noc-ok .noc-dot{background:#76cf9f;box-shadow:0 0 0 5px #76cf9f22}
.noc-attention{border-color:#f5b84a5c}
.noc-attention .noc-dot{background:var(--lamplight);box-shadow:0 0 0 5px #f5b84a22}
.noc-down{border-color:#e8927c66}
.noc-down .noc-dot{background:#e8927c;box-shadow:0 0 0 5px #e8927c26}
.noc-verdict-facts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:0}
.noc-verdict-facts>div{display:grid;gap:3px;min-width:0}
.noc-verdict-facts dt{color:var(--dim);font-size:.66rem;letter-spacing:.04em;text-transform:uppercase}
.noc-verdict-facts dd{margin:0;font-size:.86rem;font-weight:700;color:var(--paper)}

.noc-feed{display:grid;gap:8px;margin:0;padding:0;list-style:none}
.noc-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:start;padding:13px 15px;border:1px solid var(--line);border-left-width:3px;border-radius:10px;background:#171d2d}
.noc-item strong{display:block;font-size:.84rem;color:var(--paper)}
.noc-item strong a{color:inherit}
.noc-item span{display:block;margin-top:3px;color:var(--dim);font-size:.75rem;line-height:1.45}
.noc-item-badge{padding:3px 8px;border-radius:999px;font-size:.6rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap}
.noc-item.noc-attention{border-left-color:var(--lamplight)}
.noc-item.noc-attention .noc-item-badge{color:#10131f;background:var(--lamplight)}
.noc-item.noc-down{border-left-color:#e8927c}
.noc-item.noc-down .noc-item-badge{color:#10131f;background:#e8927c}
.noc-clear{margin:0;padding:16px;border:1px solid #76cf9f33;border-radius:10px;background:#76cf9f0f;color:#a7dcc1;font-size:.84rem}

.noc-signals{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}
.noc-signals article{display:grid;gap:5px;padding:14px;border:1px solid var(--line);border-left-width:3px;border-radius:11px;background:#171d2d;min-width:0}
.noc-signals span{color:var(--dim);font-size:.67rem;letter-spacing:.03em;text-transform:uppercase}
.noc-signals strong{font-size:.95rem;font-weight:700;color:var(--paper);overflow-wrap:anywhere}
.noc-signals .noc-good{border-left-color:#76cf9f}
.noc-signals .noc-warn{border-left-color:var(--lamplight)}
.noc-signals .noc-bad{border-left-color:#e8927c}

/* --- the customer directory -------------------------------------------------
   Was an eight-column table that wrapped every date onto two lines, broke email
   addresses mid-word, and printed "Not collected" as the headline for families
   who simply never gave a name. Rows instead: one family each, the address as
   the identity when there is no name, and facts in a grid that reflows rather
   than scrolling sideways. */
.customer-grid{display:grid;gap:10px}
.customer-row{display:grid;gap:12px;padding:16px 18px;border:1px solid var(--line);border-radius:12px;background:#171d2d}
.customer-identity{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:10px}
.customer-email,.customer-email-primary{overflow-wrap:anywhere}
.customer-email-primary{font-size:.92rem}
.customer-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.customer-fact{display:grid;gap:2px;min-width:0}
.customer-fact>span{color:var(--dim);font-size:.63rem;letter-spacing:.05em;text-transform:uppercase}
.customer-fact>strong{font-size:.84rem;font-weight:700;color:var(--paper);overflow-wrap:anywhere}
.customer-fact>small{color:var(--dim);font-size:.7rem;overflow-wrap:anywhere}
.customer-note{margin:0;font-size:.72rem;color:var(--dim)}
.tag-comp{font-style:normal;padding:1px 7px;border-radius:999px;background:#76cf9f22;color:#a7dcc1;font-size:.66rem;font-weight:800}
.state-good{color:#8fd8b3}.state-warn{color:var(--lamplight)}.state-bad{color:#f0a894}.state-idle{color:var(--dim)}

@media (max-width:860px){
  .noc-verdict-facts,.noc-signals{grid-template-columns:repeat(2,minmax(0,1fr))}
  .customer-facts{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* The stake on an unmarked card: a number Canvas published, deliberately quieter
   than a real score so the two can never be confused at a glance. */
.dashboard-stake{color:var(--dim);font-weight:650;font-size:.78rem}
.dashboard-group-note{margin:-.2rem 0 .7rem;color:var(--dim);font-size:.82rem;line-height:1.45}
