/* shell.css — the palette and the menu panel, defined once.
 *
 * WHY THIS FILE EXISTS
 * The same panel had been hand-copied into three pages — /app, /calendar and
 * /admin — because there was no shared stylesheet to put it in and each page is
 * a standalone HTML file. Nobody chose that; it accumulated, one reasonable
 * instruction at a time. It was already drifting: three copies with three
 * different scoping strategies and three sets of class names, so adding a nav
 * item or fixing a hover state was three edits that would silently fall out of
 * step.
 *
 * Source of the design: prototypes/canvas-video-mockup/index.html.
 *
 * login.html keeps its smaller token vocabulary, but now follows the same
 * five-family × two-mode contract as the authenticated shell.
 */

@font-face{font-family:'LiANN Nunito';src:url('/fonts/nunito-black.ttf') format('truetype');
  font-style:normal;font-weight:900;font-display:swap}

/* ---- palette ------------------------------------------------------------
 * Five families x two modes. The values mirror the Pinyin app family so a
 * learner's appearance choice feels continuous across Learning with LiANN.
 *
 * THE SCOPE IS CHOSEN BY WHERE YOU PUT `.sh-theme`, and that is the whole trick
 * that lets one palette serve pages with opposite needs:
 *
 *   <body class="sh-theme">      the page adopts the palette   (/app, /admin)
 *   <aside class="sh-side sh-theme">   ONLY the panel does      (/calendar)
 *
 * /calendar needs the second: it defines --card, --border, --hairline and
 * --muted itself, with different values, and the owner asked for the panel to
 * match the mockup while the calendar keeps its own look. Custom properties
 * inherit, so declaring them on the panel overrides them for that subtree and
 * nothing else. The data attributes always live on <html>, so `.sh-theme` is
 * always a descendant and one selector covers both cases.
 */
html[data-family="cadence"][data-theme="light"] .sh-theme,
html[data-family="cadence"][data-theme="light"].sh-theme{
  --page:#FAF5EC;--app:#F7F1E7;--raised:#F2EBDD;--card:#F7F1E7;--hover:#E7DDCA;
  --hairline:#E7DDCA;--border:#DDD1BD;--border-strong:#B8A995;--text:#1C1712;--body:#4D443A;
  --muted:#6D6256;--faint:#887B6C;--accent:#A86A1F;--accent-wash:rgba(168,106,31,.15);
  --on-accent:#FFFFFF;--live:#287348;--record:#AA3834;--cue:#2E8B7B;--shadow:rgba(36,28,18,.16)}
html[data-family="cadence"][data-theme="dark"] .sh-theme,
html[data-family="cadence"][data-theme="dark"].sh-theme{
  --page:#14110F;--app:#211C18;--raised:#191512;--card:#211C18;--hover:#2C2621;
  --hairline:#2C2621;--border:#38312B;--border-strong:#5B5148;--text:#EFE6D8;--body:#D8CBBB;
  --muted:#B3A596;--faint:#8F8376;--accent:#E0A141;--accent-wash:rgba(224,161,65,.22);
  --on-accent:#1C1005;--live:#62C28A;--record:#F0746F;--cue:#57B4A4;--shadow:rgba(0,0,0,.5)}
html[data-family="amber"][data-theme="light"] .sh-theme,
html[data-family="amber"][data-theme="light"].sh-theme{
  --page:#F5EEE2;--app:#FFFFFF;--raised:#FCFAF6;--card:#FBF8F2;--hover:#F1E9DC;
  --hairline:#ECE6DD;--border:#E1D9CC;--border-strong:#D3C8B6;--text:#1A1712;--body:#35302A;
  --muted:#6B655C;--faint:#8A8072;--accent:#B07C2D;--accent-wash:rgba(176,124,45,.15);
  --on-accent:#FFFFFF;--live:#4E9A6B;--record:#C25B44;--cue:#2E8B7B;--shadow:rgba(40,30,12,.16)}
html[data-family="amber"][data-theme="dark"] .sh-theme,
html[data-family="amber"][data-theme="dark"].sh-theme{
  --page:#14110D;--app:#1E1A15;--raised:#191510;--card:#221D17;--hover:#2A241C;
  --hairline:#2E2820;--border:#3A342B;--border-strong:#4A4239;--text:#F3EEE5;--body:#E4DDD2;
  --muted:#B4AA9C;--faint:#928878;--accent:#D89A45;--accent-wash:rgba(216,154,69,.22);
  --on-accent:#14110D;--live:#6BBE86;--record:#D9745C;--cue:#57B4A4;--shadow:rgba(0,0,0,.5)}
html[data-family="steel"][data-theme="light"] .sh-theme,
html[data-family="steel"][data-theme="light"].sh-theme{
  --page:#EDF0F4;--app:#FFFFFF;--raised:#F8FAFC;--card:#F4F7FA;--hover:#E8EDF3;
  --hairline:#E8EDF3;--border:#E0E5EC;--border-strong:#CFD7E0;--text:#10151B;--body:#2B333D;
  --muted:#5B6773;--faint:#75818E;--accent:#4A7196;--accent-wash:rgba(74,113,150,.15);
  --on-accent:#FFFFFF;--live:#4E9A6B;--record:#C25B44;--cue:#2E8B7B;--shadow:rgba(16,21,27,.18)}
html[data-family="steel"][data-theme="dark"] .sh-theme,
html[data-family="steel"][data-theme="dark"].sh-theme{
  --page:#0F1216;--app:#171B21;--raised:#13171C;--card:#1B2027;--hover:#232933;
  --hairline:#1E242C;--border:#262C35;--border-strong:#303845;--text:#EDF1F5;--body:#D8DEE6;
  --muted:#9AA6B4;--faint:#77828F;--accent:#7FA8CC;--accent-wash:rgba(127,168,204,.22);
  --on-accent:#0F1216;--live:#6BBE86;--record:#D9745C;--cue:#57B4A4;--shadow:rgba(0,0,0,.6)}
html[data-family="ivory"][data-theme="light"] .sh-theme,
html[data-family="ivory"][data-theme="light"].sh-theme{
  --page:#EFE2C8;--app:#F7EFDD;--raised:#F2E8D2;--card:#F7EFDD;--hover:#E3D5B8;
  --hairline:#E3D5B8;--border:#DAC9AA;--border-strong:#CFB996;--text:#3A3830;--body:#4A463C;
  --muted:#6B6354;--faint:#887C69;--accent:#8F5C20;--accent-wash:rgba(143,92,32,.16);
  --on-accent:#FFFFFF;--live:#287348;--record:#AA3834;--cue:#2E8B7B;--shadow:rgba(58,45,26,.18)}
html[data-family="ivory"][data-theme="dark"] .sh-theme,
html[data-family="ivory"][data-theme="dark"].sh-theme{
  --page:#201B15;--app:#2A241C;--raised:#251F17;--card:#2A241C;--hover:#352D21;
  --hairline:#352D21;--border:#3E3528;--border-strong:#453B2B;--text:#EFE6D6;--body:#D5C9B6;
  --muted:#B8AC98;--faint:#918573;--accent:#E0A141;--accent-wash:rgba(224,161,65,.22);
  --on-accent:#201305;--live:#62C28A;--record:#F0746F;--cue:#57B4A4;--shadow:rgba(0,0,0,.55)}

/* LiANN is the brand-native family, derived from the public homepage. The
   accessible deep coral is the UI accent; the brighter homepage coral remains
   available for the wordmark and large decorative treatments. */
html[data-family="liann"][data-theme="light"] .sh-theme,
html[data-family="liann"][data-theme="light"].sh-theme{
  --page:#FBF6EE;--app:#FFFDF9;--raised:#F3F0E9;--card:#FFFDF9;--hover:#E4EADF;
  --hairline:#DCE4D7;--border:#CBD6C5;--border-strong:#8A9B7E;--text:#2B2B28;--body:#40443C;
  --muted:#66705F;--faint:#818B79;--accent:#C24837;--accent-wash:#F6D9D3;
  --on-accent:#FFFFFF;--live:#6FA287;--record:#C24837;--cue:#5F7457;--shadow:rgba(74,86,66,.22);
  --brand-coral:#E2604E;--brand-sage:#8A9B7E;--brand-sage-deep:#5F7457;--brand-gold:#D9A441}
html[data-family="liann"][data-theme="dark"] .sh-theme,
html[data-family="liann"][data-theme="dark"].sh-theme{
  --page:#1B1C18;--app:#24261F;--raised:#20221C;--card:#292B24;--hover:#34392E;
  --hairline:#34392E;--border:#46503F;--border-strong:#718267;--text:#F5EFE5;--body:#E6DED2;
  --muted:#B9BDAF;--faint:#92998A;--accent:#EE7A67;--accent-wash:rgba(226,96,78,.2);
  --on-accent:#24120E;--live:#83B99C;--record:#EE7A67;--cue:#9AAF8E;--shadow:rgba(0,0,0,.5);
  --brand-coral:#EE7A67;--brand-sage:#A8B89D;--brand-sage-deep:#718267;--brand-gold:#E5B85D}

/* ---- structural grammar -------------------------------------------------
 * Unlike palette tokens these are family-only: light/dark never reflows the
 * interface. Steelline deliberately reproduces the old shared constants and
 * acts as the stable control for visual regression tests. */
html[data-family="liann"]{
  --sh-font-display:'Nunito',ui-rounded,'Arial Rounded MT Bold',system-ui,sans-serif;
  --sh-font-ui:'Nunito',ui-rounded,system-ui,-apple-system,sans-serif;
  --sh-display-weight:900;--sh-display-tracking:-.01em;--sh-ui-weight:600;
  --sh-w:248px;--sh-r:16px;--sh-r-nav:999px;--sh-gap:6px;
  --sh-side-pad:20px 14px;--sh-nav-pad:12px 14px;--sh-card-pad:12px 10px;
  --sh-card-border:0px;--sh-card-shadow:0 8px 22px -14px var(--shadow);
  --sh-motion:200ms cubic-bezier(.2,.7,.3,1);--sh-stroke:2;--sh-line:1.6}
html[data-family="cadence"]{
  --sh-font-display:'Spectral',Georgia,'Times New Roman',serif;
  --sh-font-ui:Georgia,'Times New Roman',serif;
  --sh-display-weight:600;--sh-display-tracking:0;--sh-ui-weight:400;
  --sh-w:260px;--sh-r:3px;--sh-r-nav:0;--sh-gap:2px;
  --sh-side-pad:18px 14px;--sh-nav-pad:9px 12px;--sh-card-pad:12px 8px;
  --sh-card-border:1px;--sh-card-shadow:none;
  --sh-motion:260ms ease;--sh-stroke:1.4;--sh-line:1.7}
html[data-family="amber"]{
  --sh-font-display:'Hanken Grotesk','Arial Narrow','Segoe UI',system-ui,sans-serif;
  --sh-font-ui:'Hanken Grotesk','Arial Narrow','Segoe UI',system-ui,sans-serif;
  --sh-display-weight:800;--sh-display-tracking:-.025em;--sh-ui-weight:500;
  --sh-w:224px;--sh-r:8px;--sh-r-nav:8px;--sh-gap:3px;
  --sh-side-pad:12px 10px;--sh-nav-pad:8px 10px;--sh-card-pad:10px 8px;
  --sh-card-border:0px;--sh-card-shadow:0 3px 0 var(--border-strong);
  --sh-motion:110ms ease-out;--sh-stroke:2.2;--sh-line:1.45}
html[data-family="steel"]{
  --sh-font-display:'Spectral',Georgia,'Times New Roman',serif;
  --sh-font-ui:'Hanken Grotesk','Segoe UI',system-ui,-apple-system,sans-serif;
  --sh-display-weight:600;--sh-display-tracking:0;--sh-ui-weight:400;
  --sh-w:236px;--sh-r:10px;--sh-r-nav:10px;--sh-gap:4px;
  --sh-side-pad:16px 12px;--sh-nav-pad:10px;--sh-card-pad:10px 8px;
  --sh-card-border:1px;--sh-card-shadow:none;
  --sh-motion:180ms ease;--sh-stroke:1.7;--sh-line:1.5}
html[data-family="ivory"]{
  --sh-font-display:'Spectral',Georgia,'Times New Roman',serif;
  --sh-font-ui:'Segoe UI Light','Helvetica Neue',Arial,sans-serif;
  --sh-display-weight:400;--sh-display-tracking:.06em;--sh-ui-weight:300;
  --sh-w:272px;--sh-r:0;--sh-r-nav:0;--sh-gap:10px;
  --sh-side-pad:24px 18px;--sh-nav-pad:14px 12px;--sh-card-pad:16px 8px;
  --sh-card-border:1px;--sh-card-shadow:none;
  --sh-motion:0ms linear;--sh-stroke:1.2;--sh-line:1.75}

:root{--sh-w:236px;--sh-r:10px;--sh-r-nav:10px;--sh-gap:4px;
  --sh-side-pad:16px 12px;--sh-nav-pad:10px;--sh-card-pad:10px 8px;
  --sh-card-border:1px;--sh-card-shadow:none;--sh-motion:180ms ease;
  --sh-stroke:1.7;--sh-line:1.5;--sh-display-weight:600;--sh-display-tracking:0;
  --sh-ui-weight:400;--sh-font-display:Georgia,serif;--sh-font-ui:system-ui,sans-serif}

/* ---- the panel ---------------------------------------------------------- */
.sh-side{
  background:var(--app);border-right:1px solid var(--border);color:var(--body);
  display:flex;flex-direction:column;gap:var(--sh-gap);padding:var(--sh-side-pad);
  font-family:var(--sh-font-ui);font-size:14px;font-weight:var(--sh-ui-weight);line-height:var(--sh-line)}
.sh-side .ic{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:var(--sh-stroke);
  stroke-linecap:round;stroke-linejoin:round;flex:none}

.sh-brand{display:flex;align-items:center;gap:10px;font-family:var(--sh-font-display);
  font-size:20px;color:var(--text);font-weight:var(--sh-display-weight);letter-spacing:var(--sh-display-tracking);
  padding:6px 8px 12px}
.sh-dot{width:11px;height:11px;border-radius:3px;background:var(--accent);flex:none}

.sh-wordmark{display:inline-flex;flex-flow:row nowrap;align-items:baseline;column-gap:.16em;row-gap:0;
  min-width:0;max-width:100%;flex-shrink:1;font-family:'LiANN Nunito','Nunito',ui-rounded,system-ui,sans-serif!important;
  font-weight:900!important;line-height:.98;letter-spacing:-.035em;text-transform:none!important;white-space:normal!important}
.sh-wordmark-prefix,.sh-wordmark-name{flex:0 0 auto;white-space:nowrap}
.sh-wordmark-prefix{background:linear-gradient(90deg,var(--brand-sage-deep,#5F7457),var(--brand-sage,#8A9B7E));
  color:transparent!important;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent!important}
.sh-wordmark-name{background:none!important;color:var(--brand-coral,#E2604E)!important;
  letter-spacing:-.025em;-webkit-text-fill-color:var(--brand-coral,#E2604E)!important}

@media(forced-colors:active){.sh-wordmark-prefix,.sh-wordmark-name{background:none!important;
  color:CanvasText!important;-webkit-text-fill-color:CanvasText!important}}
@media(max-width:820px){.sh-wordmark{flex-wrap:wrap}}

.sh-who{display:flex;align-items:center;gap:10px;padding:var(--sh-card-pad);margin-bottom:8px;
  border-radius:var(--sh-r);background:var(--card);border:var(--sh-card-border) solid var(--hairline);
  box-shadow:var(--sh-card-shadow);transition:box-shadow var(--sh-motion),border-color var(--sh-motion)}
.sh-who .av{width:34px;height:34px;border-radius:50%;background:var(--accent-wash);
  color:var(--accent);display:grid;place-items:center;font-weight:600;flex:none}
.sh-who .nm{font-size:13px;color:var(--text);font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sh-who .rl{font-size:11px;color:var(--muted)}
.sh-who > span:last-child{min-width:0}

.sh-nav{border:0;background:transparent;width:100%;display:flex;align-items:center;gap:11px;
  padding:var(--sh-nav-pad);border-radius:var(--sh-r-nav);color:var(--muted);cursor:pointer;
  font-family:inherit;font-size:14px;text-align:left;text-decoration:none;
  transition:background var(--sh-motion),color var(--sh-motion),box-shadow var(--sh-motion)}
.sh-nav:hover{background:var(--hover);color:var(--body)}
/* Both spellings are current: /app and /admin switch views and mark the active
   one aria-current="true"; /calendar is a real page and marks it "page". */
.sh-nav[aria-current="true"],
.sh-nav[aria-current="page"]{background:var(--accent-wash);color:var(--accent);font-weight:500}

html[data-family="liann"] .sh-nav[aria-current]{font-weight:700}
html[data-family="cadence"] .sh-nav[aria-current]{background:transparent;border-left:2px solid var(--accent);
  color:var(--accent);font-weight:600;padding-left:10px}
html[data-family="amber"] .sh-nav[aria-current]{background:var(--accent);color:var(--on-accent);
  font-weight:800;box-shadow:inset 4px 0 0 var(--border-strong)}
html[data-family="ivory"] .sh-nav[aria-current]{background:transparent;color:var(--text);font-weight:400;
  text-transform:uppercase;letter-spacing:.1em;text-decoration:underline;text-underline-offset:6px}

html[data-family="cadence"] .sh-who{border-width:1px 0;border-radius:0;box-shadow:none}
html[data-family="amber"] .sh-who{border:0;border-left:4px solid var(--accent);box-shadow:var(--sh-card-shadow)}
html[data-family="ivory"] .sh-who{border-width:1px 0;border-radius:0;box-shadow:none}
/* A nav item with nowhere to go says so, rather than landing you elsewhere. */
.sh-nav[aria-disabled="true"]{opacity:.45;cursor:default}
.sh-nav[aria-disabled="true"]:hover{background:transparent;color:var(--muted)}
.sh-nav .badge{margin-left:auto;font-size:11px;background:var(--accent);color:var(--on-accent);
  border-radius:999px;padding:1px 7px}

.sh-foot{margin-top:auto;padding-top:12px;border-top:1px solid var(--hairline)}
.sh-seg{display:flex;flex-wrap:wrap;background:var(--card);border:1px solid var(--border);border-radius:var(--sh-r-nav);
  padding:3px;margin-bottom:6px;gap:2px}
.sh-seg button{flex:1;border:0;background:transparent;color:var(--muted);cursor:pointer;
  font-family:inherit;font-size:12px;padding:5px;border-radius:var(--sh-r-nav);
  display:inline-flex;align-items:center;justify-content:center;gap:5px;transition:background var(--sh-motion),color var(--sh-motion)}
.sh-seg button[data-fam]{flex:1 1 46%;font-size:11px;padding-inline:4px;letter-spacing:-.02em}
.sh-seg button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent)}
html[data-family="cadence"] .sh-seg{border-width:1px 0;border-radius:0;background:transparent}
html[data-family="cadence"] .sh-seg button[aria-pressed="true"]{background:transparent;color:var(--accent);box-shadow:inset 2px 0 var(--accent)}
html[data-family="amber"] .sh-seg{box-shadow:0 2px 0 var(--border-strong)}
html[data-family="ivory"] .sh-seg{border-width:0 0 1px;border-radius:0;background:transparent}
html[data-family="ivory"] .sh-seg button{border-radius:0;text-transform:uppercase;letter-spacing:.08em}
html[data-family="ivory"] .sh-seg button[aria-pressed="true"]{background:transparent;color:var(--text);text-decoration:underline}

@media(prefers-reduced-motion:reduce){.sh-side *,.sh-nav,.sh-seg button{transition:none!important}}

/* ---- open / closed ------------------------------------------------------
 * One class on <body>. Each page keeps its own grid, because their layouts
 * genuinely differ (/admin and /app are full-height app shells, /calendar is a
 * document with a header above it), but the panel's own show/hide is here so
 * the three cannot disagree about what "open" means.
 */
body.sh-nav-open .sh-side{display:flex}
.sh-side{display:none}

@media(max-width:820px){
  /* Off-canvas: it must not squeeze the content on a small screen. */
  body.sh-nav-open .sh-side{position:fixed;top:var(--sh-top,57px);left:0;bottom:0;
    width:var(--sh-w);z-index:300;overflow-y:auto;box-shadow:0 18px 60px rgba(0,0,0,.28)}

  /* THE SCRIM IS CSS, NOT JAVASCRIPT, and that is a fix rather than a style
     choice. Built by the open handler it exists only when you open the panel
     while ALREADY narrow — so opening it on a wide screen and then narrowing
     the window left a drawer over the page with no scrim behind it and nothing
     to dismiss it by tapping. Bound to the same breakpoint as the drawer, it
     cannot be present without the drawer or absent with it, at any width.
     A pseudo-element takes no listener of its own, but clicks on it report
     <body> as the target, which is what shell.js listens for. */
  body.sh-nav-open::after{content:"";position:fixed;top:var(--sh-top,57px);left:0;right:0;
    bottom:0;background:rgba(0,0,0,.35);z-index:290}
}
