/* ===== Academy Hub app shell: the console's hardware edge (CARTRIDGE design system, tokens in /theme.css) =====
   Loaded last in /it/ and /ai/, and by the hub. Owns: the app switcher (cartridge-slot rail on wide screens, button
   deck along the bottom on narrow ones), safe areas, dvh heights, the top bar's overflow ("More") row, the two-pane
   layout when unfolded, 44px tap targets, the update banner and print. Content CSS is untouched. */
:root {
  --sa-t: env(safe-area-inset-top, 0px); --sa-r: env(safe-area-inset-right, 0px);
  --sa-b: env(safe-area-inset-bottom, 0px); --sa-l: env(safe-area-inset-left, 0px);
  --top-h: calc(60px + var(--sa-t));
  --nav-h: 68px; --rail-w: 84px;
  --app-b: calc(var(--nav-h) + var(--sa-b));   /* space taken by the bottom button deck */
  --app-l: 0px;                                 /* space taken by the side rail */
  --app-r: var(--sa-r);
  --vh: 100vh; --vh: 100dvh;
}
@media (min-width: 760px) {
  :root { --app-b: var(--sa-b); --app-l: calc(var(--rail-w) + var(--sa-l)); }
}
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
html, body { max-width: 100%; overflow-x: clip; }
body { padding-left: var(--app-l); padding-right: var(--app-r); padding-bottom: var(--app-b); }
@media (display-mode: standalone) { html { overscroll-behavior-y: none; } }
a, button, summary, label, input, select, textarea, [role="button"], .btn { touch-action: manipulation; }
.sidebar, .search-results, .w-log, .rd-box, .rd-choices, .modal, .app-nav { overscroll-behavior: contain; }
.app-nav, .app-nav * { -webkit-user-select: none; user-select: none; }

/* ---- the academy pages: top bar respects notch/cutout + safe areas ---- */
html.app-academy .topbar { height: var(--top-h); padding-top: var(--sa-t); padding-left: max(14px, var(--sa-l)); }
@media (min-width: 760px) { html.app-academy .topbar { padding-left: 14px; } }
html.app-academy .layout { min-height: calc(var(--vh) - var(--top-h) - var(--app-b)); }
html.app-academy .sidebar { height: calc(var(--vh) - var(--top-h) - var(--app-b)); }
html.app-academy .scrim { left: var(--app-l); bottom: var(--app-b); }
html.app-academy .rpg-world { height: calc(var(--vh) - var(--top-h) - var(--app-b)); }
html.app-academy .rpg-title { min-height: calc(var(--vh) - var(--top-h) - var(--app-b)); }
html.app-academy .prologue .t-inner { height: calc(var(--vh) - var(--top-h) - var(--app-b)); }
html.app-academy body.rpg.rpg-full .rpg-battle { min-height: calc(var(--vh) - var(--top-h) - var(--app-b)); }
html.app-academy .rpg-dialog:not(.in-host) { left: calc(50% + var(--app-l) / 2); bottom: calc(18px + var(--app-b)); width: min(860px, calc(100vw - var(--app-l) - var(--app-r) - 24px)); }
/* a dialog hosted inside the overworld is sized by its host (the host is narrower than the viewport beside the rail) */
html.app-academy .rpg-world > .rpg-dialog.in-host { width: min(860px, calc(100% - 24px)); }
html.app-academy .toast { left: calc(50% + var(--app-l) / 2); bottom: calc(22px + var(--app-b)); max-width: calc(100vw - var(--app-l) - 24px); }
html.app-academy .game-pop { left: calc(50% + var(--app-l) / 2); max-width: calc(100vw - var(--app-l) - 24px); }
html.app-academy .search-results { max-height: min(70vh, calc(var(--vh) - var(--top-h) - var(--app-b) - 20px)); }
html.app-academy .w-hud { max-width: min(340px, calc(100% - 24px)); }
@media (min-width: 761px) {   /* HUD (left) and action buttons (right) share the top row without overlapping */
  html.app-academy .w-hud { max-width: min(340px, calc(40% - 18px)); }
  html.app-academy .w-actions { max-width: calc(60% - 18px); }
}
@media (min-width: 761px) and (max-height: 480px) {   /* landscape cover screen: compact HUD */
  html.app-academy .w-hud { padding: 4px 8px; } html.app-academy .w-banner { top: 30%; }
}
img, canvas, video, svg, pre, table { max-width: 100%; }
html.app-academy .content { min-width: 0; overflow-wrap: anywhere; }
html.app-academy .content pre, html.app-academy .content .CodeMirror, html.app-academy .content table { overflow-x: auto; }
html.app-academy .content table { display: block; }
html.app-academy .content code { overflow-wrap: anywhere; }

/* Off-canvas sidebar (narrow, or RPG full-screen routes) sits beside the rail and above the button deck. */
html.app-academy .sidebar { overscroll-behavior: contain; }
@media (max-width: 959.98px) {
  html.app-academy .sidebar { left: var(--app-l); top: var(--top-h); bottom: var(--app-b); max-width: calc(100vw - var(--app-l) - 16px); }
}
html.app-academy body.rpg .sidebar { left: var(--app-l); bottom: var(--app-b); max-width: calc(100vw - var(--app-l) - 16px); }

/* ---- Top bar: never overflows. Key chips stay in row 1; the rest folds into a "⋯ More" tray (DOM order and
   event listeners untouched: .topbar-right becomes display:contents and items are re-ordered with flex order;
   the row break is the empty .app-more-break element that app-shell.js adds next to the More button). ---- */
html.app-academy .topbar { --tb-gap: 6px; flex-wrap: wrap; align-content: flex-start; row-gap: 0; column-gap: var(--tb-gap); padding-right: max(10px, var(--sa-r)); }
html.app-academy .topbar.more-open { height: auto; min-height: var(--top-h); padding-bottom: 10px; }
html.app-academy .topbar-right { display: contents; }
html.app-academy .topbar > *, html.app-academy .topbar-right > * { order: 20; flex: none; }
html.app-academy .topbar > .menu-btn { order: 1; } html.app-academy .topbar > .brand { order: 2; }
html.app-academy .topbar > .search-wrap { order: 3; flex: 1 1 60px; min-width: 44px; max-width: 520px; margin-left: 4px; }
html.app-academy #xpChip { order: 6; } html.app-academy #goldChip { order: 7; } html.app-academy #hqBtn { order: 8; } html.app-academy #acctChip { order: 9; }
@media (max-width: 999.98px) { html.app-academy .topbar #hqBtn .hq-label { display: none; } }
/* the decorative logo strip (aria-hidden) only where row 1 has room for it next to the name, search and key chips */
@media (max-width: 1099.98px) { html.app-academy .topbar .brand-logo { display: none; } }
html.app-academy .topbar > .app-more { order: 10; }
html.app-academy .topbar > *, html.app-academy .topbar-right > *:not(.py-status) { height: auto; min-height: 44px; margin-top: 8px; }
html.app-academy .topbar > .brand { min-height: 44px; }
/* the row break; when the tray is open it becomes the dashed seam between the status row and the tray */
html.app-academy .topbar > .app-more-break { order: 15; flex: 0 0 100%; height: 0; min-height: 0; margin: 0; padding: 0; border: 0; pointer-events: none; }
html.app-academy .topbar.more-open > .app-more-break { margin-top: 8px; border-top: 2px dashed var(--k-hair); }
@media (max-width: 1319.98px) { html.app-academy .topbar:not(.more-open) .topbar-right > :not(#xpChip):not(#goldChip):not(#acctChip):not(#hqBtn) { display: none !important; } }
/* laptop widths: the path chip also stays in row 1 (the search box gives up the room); the rest is in the tray */
@media (min-width: 1320px) and (max-width: 1599.98px) {
  html.app-academy .topbar:not(.more-open) .topbar-right > :not(#xpChip):not(#goldChip):not(#acctChip):not(#hqBtn):not(#trackChip) { display: none !important; }
  html.app-academy #trackChip { order: 5; }
}
html.app-academy .topbar [hidden] { display: none !important; }
html.app-academy .topbar.more-open #trackChip, html.app-academy .topbar.more-open #hqBtn, html.app-academy .topbar.more-open #streakChip,
html.app-academy .topbar.more-open #soundBtn, html.app-academy .topbar.more-open #themeBtn { display: inline-flex; align-items: center; justify-content: center; }
html.app-academy .topbar.more-open .tc-name { display: inline; }
html.app-academy .topbar.more-open .py-status { display: none !important; }
html.app-academy .topbar .icon-btn, html.app-academy .topbar .xp-chip, html.app-academy .topbar .gold-chip, html.app-academy .topbar .track-chip,
html.app-academy .topbar .acct-chip, html.app-academy .topbar .streak-chip, html.app-academy .topbar .app-more { min-height: 44px; min-width: 44px; }
/* ids on purpose: the chip skins set their own (smaller) minimums with id / body.rpg selectors */
html.app-academy .topbar #acctChip, html.app-academy .topbar #goldChip { min-height: 44px; min-width: 44px; }
html.app-academy .topbar .icon-btn, html.app-academy .topbar .app-more { padding-left: 8px; padding-right: 8px; }
html.app-academy .topbar .gold-chip, html.app-academy .topbar .acct-chip, html.app-academy .topbar .streak-chip { display: inline-flex; align-items: center; justify-content: center; }
/* the More key: same recipe as every console key; lit in coin yellow and held down while the tray is open */
html.app-academy .app-more { display: inline-flex; align-items: center; justify-content: center; font: 700 1.25rem/1 var(--k-body); cursor: pointer;
  color: var(--k-text); background: var(--k-panel); border: var(--k-border); border-radius: var(--k-r-sm); box-shadow: var(--k-drop-sm);
  transition: transform .08s, box-shadow .08s, background .08s; }
html.app-academy .app-more:hover { background: var(--k-inset); }
html.app-academy .app-more:active { transform: translate(2px, 2px); box-shadow: none; }
html.app-academy .app-more[aria-expanded="true"] { background: var(--k-coin); color: var(--k-on-accent); transform: translate(2px, 2px); box-shadow: none; }
@media (min-width: 1600px) {   /* everything fits in one row: no More button */
  html.app-academy .topbar { flex-wrap: nowrap; }
  html.app-academy .topbar > .app-more, html.app-academy .topbar > .app-more-break { display: none; }
  html.app-academy .topbar-right > * { order: 8; }
  html.app-academy .topbar > *, html.app-academy .topbar-right > *:not(.py-status) { margin-top: 0; }
  /* safety valve: a long path name (or account name) shortens the path chip instead of pushing chips off the bar */
  html.app-academy .topbar > .search-wrap { flex-basis: 160px; min-width: 120px; }
  html.app-academy .topbar #trackChip { flex: 0 1 auto; min-width: 44px; }
  html.app-academy .topbar #trackChip .tc-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (min-width: 1600px) and (max-width: 1699.98px) { html.app-academy .topbar .brand-logo { display: none; } }
@media (max-width: 759.98px) {
  html.app-academy .topbar { padding-left: max(8px, var(--sa-l)); }
  html.app-academy .topbar .menu-btn { display: none !important; }
}
/* phones: the brand link has no visible content there (name and logo strip are both hidden), so it must not cost a gap */
@media (max-width: 640px) { html.app-academy .topbar > .brand { margin-right: calc(-1 * var(--tb-gap)); } }
/* wide screens: the rail's Menu button replaces the top-bar one */
@media (min-width: 760px) { html.app-academy .topbar .menu-btn { display: none !important; } }
/* cover screen: tighter gaps and a search box that may shrink to an icon-sized field, so More always stays in row 1 */
@media (max-width: 380px) {
  html.app-academy .xp-track { width: 34px; }
  html.app-academy .topbar { --tb-gap: 4px; padding-left: max(6px, var(--sa-l)); padding-right: max(6px, var(--sa-r)); }
  html.app-academy .topbar > .search-wrap { flex-basis: 36px; min-width: 36px; margin-left: 0; }   /* extreme case (5-digit gold + account name): give a little more rather than wrap */
}

/* ---- touch: 16px inputs (no zoom-on-focus) and 44px tap targets everywhere ---- */
html.app-academy #searchInput { min-height: 44px; font-size: 16px; }
html.app-academy input, html.app-academy select, html.app-academy textarea { font-size: max(16px, 1em); }
html.app-academy .btn, html.app-academy .pbtn { min-height: 44px; }
html.app-academy .side-links a, html.app-academy .side-level summary, html.app-academy .side-level a { min-height: 44px; display: flex; align-items: center; }
html.app-academy .search-results .sr-item, html.app-academy .search-results .sr-all { min-height: 44px; }
html.app-academy .dp { min-width: 56px; min-height: 56px; }
html.app-academy .t-item, html.app-academy .b-opt, html.app-academy .b-cmd, html.app-academy .rd-choice { min-height: 44px; }
html.app-academy .b-opt, html.app-academy .b-cmd { display: flex; align-items: center; }
/* Guild Hall world map: long region labels near the edge never stick out past the screen */
html.app-academy .g-mapwrap { overflow: hidden; }
html.app-academy .g-pin { max-width: 44%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Wide (unfolded inner screen, landscape cover): two-pane lessons + side rail ---- */
@media (min-width: 760px) {
  html.app-academy body:not(.rpg-full) { --side-w: clamp(240px, 30vw, 300px); }
  html.app-academy body:not(.rpg-full) .sidebar,
  html.app-academy body.rpg:not(.rpg-full) .sidebar {
    position: sticky; left: auto; bottom: auto; top: var(--top-h); transform: none; max-width: none; box-shadow: none; z-index: 1;
    height: calc(var(--vh) - var(--top-h) - var(--app-b));
  }
  html.app-academy body:not(.rpg-full) .scrim { display: none !important; }
  html.app-academy body.rpg:not(.rpg-full) .content { margin: 0; max-width: none; }
  html.app-academy body:not(.rpg-full) .content { max-width: none; }
  html.app-academy body:not(.rpg-full) .content > * { max-width: 980px; }
}
/* Foldable with a reported hinge (progressive enhancement): sidebar fills the left segment. */
@media (horizontal-viewport-segments: 2) {
  html.app-academy body:not(.rpg-full) { --side-w: calc(env(viewport-segment-width 0 0, 300px) - var(--app-l)); }
  html.app-academy body:not(.rpg-full) .content { padding-left: calc(env(viewport-segment-left 1 0, 0px) - env(viewport-segment-right 0 0, 0px) + 18px); }
}

/* ===== App switcher: the hardware edge of the console =====
   One piece of bone/graphite plastic with the five-colour stripe as trim on the edge that faces the screen.
   Each app is a key with an ink outline and a hard shadow. The app you are in is latched down and lit in its
   label colour (Hub = coin, IT = orange, AI = ultraviolet) with a green power LED, like an inserted cartridge. */
.app-nav { position: fixed; z-index: 45; display: flex; background: var(--k-chrome); color: var(--k-text); font-family: var(--k-display); }
.app-nav::before { content: ""; position: absolute; pointer-events: none; }
.app-nav a, .app-nav button { --slot: var(--k-coin); position: relative; flex: 1; display: flex; align-items: center; justify-content: center; min-height: 46px; min-width: 44px; margin: 0;
  color: var(--k-text); background: var(--k-panel); border: var(--k-border); border-radius: var(--k-r-sm); box-shadow: var(--k-drop-sm);
  font: 400 1.25rem/1 var(--k-display); letter-spacing: .06em; text-transform: uppercase; text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: transform .08s, box-shadow .08s, background .08s; }
.app-nav [data-app="it"] { --slot: var(--k-it); }
.app-nav [data-app="ai"] { --slot: var(--k-ai); }
.app-nav .ic { font-family: var(--k-body); font-size: 1.3rem; line-height: 1; }
.app-nav .lbl { line-height: 1; }
.app-nav button .ic { font-weight: 700; }
@media (hover: hover) { .app-nav a:hover, .app-nav button:hover { background: var(--k-inset); } }
.app-nav a:active, .app-nav button:active { transform: translate(2px, 2px); box-shadow: none; }
.app-nav a:focus-visible, .app-nav button:focus-visible { outline: 3px solid var(--k-coin); outline-offset: 2px; }
[data-theme="light"] .app-nav a:focus-visible, [data-theme="light"] .app-nav button:focus-visible { outline-color: var(--k-link); }
/* inserted / held down */
.app-nav [aria-current="page"], .app-nav [aria-current="page"]:hover,
.app-nav button[aria-expanded="true"], .app-nav button[aria-expanded="true"]:hover { background: var(--slot); color: var(--k-on-accent); transform: translate(2px, 2px); box-shadow: none; }
/* power light on the inserted cartridge (deck: a light bar in the key's top edge; rail: the ridge lights up) */
.app-nav [aria-current="page"]::after { content: ""; position: absolute; top: -2px; right: 9px; width: 22px; height: 7px; border-radius: 0 0 4px 4px;
  background: var(--k-leaf); border: 2px solid var(--k-black); }
.app-nav .badge-dot { position: absolute; top: 5px; left: 5px; width: 9px; height: 9px; border-radius: 50%; background: var(--k-heart); border: 2px solid var(--k-black); }
.app-nav .spacer { display: none; }

/* narrow: a deck of keys along the bottom edge, stripe trim on top */
@media (max-width: 759.98px) {
  .app-nav { left: 0; right: 0; bottom: 0; height: var(--app-b); align-items: flex-start; gap: 8px;
    padding: 15px max(8px, var(--sa-r)) 0 max(8px, var(--sa-l)); border-top: var(--k-border); }
  .app-nav::before { left: 0; right: 0; top: 0; height: 5px; background: var(--k-stripes); border-bottom: var(--k-border); }
  .app-nav a, .app-nav button { flex-direction: row; gap: 6px; padding: 0 4px; }
  .app-nav .rail-only { display: none; }
}
@media (max-width: 359.98px) { .app-nav { gap: 6px; } .app-nav a, .app-nav button { gap: 4px; letter-spacing: .03em; } }

/* wide: a rail of cartridge slots down the left edge, stripe trim on the right */
@media (min-width: 760px) {
  .app-nav { top: 0; bottom: 0; left: 0; width: var(--app-l); flex-direction: column; justify-content: flex-start; gap: 10px;
    padding: calc(var(--sa-t) + 8px) 18px calc(var(--sa-b) + 12px) calc(8px + var(--sa-l)); border-right: var(--k-border); }
  .app-nav::before { top: 0; bottom: 0; right: 0; width: 5px; border-left: var(--k-border);
    background: linear-gradient(180deg, var(--k-heart) 0 20%, var(--k-it) 20% 40%, var(--k-coin) 40% 60%, var(--k-leaf) 60% 80%, var(--k-sky) 80% 100%); }
  /* a slot: moulded grip ridge on top, label below */
  .app-nav a, .app-nav button { flex: 0 0 auto; flex-direction: column; gap: 3px; min-height: 70px; padding: 13px 2px 5px; font-size: 1.2rem; border-radius: 5px 5px var(--k-r-sm) var(--k-r-sm); }
  .app-nav a::before, .app-nav button::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 9px; border-bottom: var(--k-border); border-radius: 3px 3px 0 0;
    background: repeating-linear-gradient(90deg, var(--k-muted) 0 5px, transparent 5px 9px) center / 32px 3px no-repeat, var(--k-inset); }
  /* inserted: the ridge goes dark and its ribs light up green instead of the corner LED */
  .app-nav [aria-current="page"]::before { background: repeating-linear-gradient(90deg, var(--k-leaf) 0 5px, transparent 5px 9px) center / 32px 3px no-repeat, var(--k-black); }
  .app-nav [aria-current="page"]::after { display: none; }
  .app-nav .ic { font-size: 1.45rem; }
  .app-nav .nav-menu { display: none; }
  .app-nav .spacer { display: block; flex: 1; }
  body.rpg-full .app-nav .nav-menu { display: flex; }
  /* speaker grille moulded into the bottom of the rail */
  .app-nav::after { content: ""; flex: none; align-self: center; width: 41px; height: 32px; margin-top: auto; pointer-events: none;
    background: radial-gradient(circle, var(--k-hair) 2.4px, transparent 2.9px) 0 0 / 9px 9px; }
}
@media (max-height: 520px) and (min-width: 760px) { .app-nav::after { display: none; } }
@media (max-height: 420px) and (min-width: 760px) { .app-nav { gap: 6px; padding-top: calc(var(--sa-t) + 6px); padding-bottom: calc(var(--sa-b) + 6px); } .app-nav a, .app-nav button { min-height: 54px; padding: 14px 2px 3px; gap: 0; font-size: 1.05rem; } .app-nav .ic { font-size: 1.05rem; } }

/* ===== Update / offline banner: a system notice card that pops up over the deck ===== */
.app-banner { position: fixed; z-index: 80; left: calc(50% + var(--app-l) / 2); transform: translateX(-50%); bottom: calc(var(--app-b) + 14px);
  display: flex; gap: 8px; align-items: center; width: max-content; max-width: calc(100vw - var(--app-l) - var(--app-r) - 24px); padding: 13px 8px 8px 14px; overflow: hidden;
  color: var(--k-text); background: var(--k-panel); border: var(--k-border); border-radius: var(--k-r); box-shadow: var(--k-drop-lg); font: 600 .95rem/1.35 var(--k-body); }
.app-banner::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 5px; background: var(--k-stripes); border-bottom: var(--k-border); }
.app-banner > span { flex: 1 1 auto; min-width: 0; padding-right: 4px; }
.app-banner button { flex: none; min-height: 44px; min-width: 44px; padding: 0 16px; cursor: pointer; color: var(--k-on-accent); background: var(--k-coin); border: var(--k-border); border-radius: var(--k-r-sm);
  box-shadow: var(--k-drop-sm); font: 400 1.3rem/1 var(--k-display); letter-spacing: .03em; transition: transform .08s, box-shadow .08s; }
.app-banner button:active { transform: translate(2px, 2px); box-shadow: none; }
.app-banner button.ghost { padding: 0; color: var(--k-muted); background: transparent; border-color: transparent; box-shadow: none; font: 700 1.05rem/1 var(--k-body); }
.app-banner button.ghost:hover { color: var(--k-text); background: var(--k-inset); }
.app-banner button:focus-visible { outline: 3px solid var(--k-coin); outline-offset: 2px; }
[data-theme="light"] .app-banner button:focus-visible { outline-color: var(--k-link); }

@media (prefers-reduced-motion: reduce) {
  html.app-academy .sidebar { transition: none !important; }
  .app-nav *, .app-banner *, html.app-academy .app-more { transition: none !important; }
}
@media print { .app-nav, .app-banner, .app-more, .app-more-break { display: none !important; } body { padding: 0 !important; } }
