/* ADM-11-01 — web foundation on design tokens v0.3: palettes, brand header, grouped menu, shared components.
   Values mirror design/tokens/v0.3/design-tokens-delta.json; test/web-accessibility-audit.test.mjs checks they match
   and measures every text/background pair. Admin keeps the neutral v0.2 color.web.* (DD-13); the parent web swaps
   the same variables for color.webWarm.* (U-42), so every existing page turns warm without per-page CSS. */
:root{--web-hero:var(--tb-color-web-subtle);--web-nav-selected:var(--tb-color-web-subtle);--web-card-border:var(--tb-color-web-line);--web-primary-hover:var(--tb-color-web-primary);--web-primary-edge:var(--tb-color-web-primary);--web-heading-font:'Lexend',system-ui,sans-serif}
html[data-palette=warm]{--tb-color-web-canvas:#FFF8F0;--tb-color-web-surface:#FFFFFF;--tb-color-web-subtle:#FDEEDF;--tb-color-web-ink:#2B211C;--tb-color-web-muted:#6B5548;--tb-color-web-line:#8C7466;--tb-color-web-primary:#B33F12;--tb-color-web-onprimary:#FFFFFF;--tb-color-web-focus:#1E3FCC;--web-hero:#FFE9D6;--web-nav-selected:#FFE2CC;--web-card-border:#F0DCCB;--web-primary-hover:#962F08;--web-primary-edge:#7A2606;--web-heading-font:'Baloo 2','Lexend',system-ui,sans-serif}

/* Type (webType, rem so browser text size scales it). Baloo 2 only on the parent web. */
h1{font-family:var(--web-heading-font);font-size:2rem;line-height:2.5rem;font-weight:700;letter-spacing:0}
html[data-palette=warm] h2{font-family:var(--web-heading-font);font-size:1.5rem;line-height:2rem}
html[data-palette=neutral] h1{font-size:1.75rem;line-height:2.25rem;font-weight:600;letter-spacing:-.01em}
@media(max-width:390px){html[data-palette=warm] h1{font-size:1.75rem;line-height:2.25rem}}

/* Brand header: logo slot + name; Bông and Đốm slots on the parent web. */
.brand-head{display:flex;flex-wrap:wrap;align-items:center;gap:12px;min-height:44px}
.brand-words{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.brand-name{font-family:var(--web-heading-font);font-size:1.25rem;font-weight:700}
.brand-sub{font-size:.875rem;color:var(--tb-color-web-muted)}
/* ADM-11-05: the 240px rail is too narrow for logo + name + mascots; the name stays whole and the mascots wrap. */
.brand-name,.brand-sub{white-space:nowrap}
.brand-mascots{display:flex;gap:4px}
.menu-toggle{margin-left:auto;display:inline-flex;align-items:center;min-width:44px;padding:8px 14px;border:2px solid var(--tb-color-web-line);border-radius:var(--tb-radius-sm);background:var(--tb-color-web-surface);color:var(--tb-color-web-ink);font-weight:600;cursor:pointer}
.menu-toggle[aria-expanded=true]{border-color:var(--tb-color-web-primary)}

/* Image slots (asset-slots.ts): the real art when built, else a blank token-coloured shape. */
.slot{display:inline-block;flex:none;width:40px;height:40px}.slot img{display:block;width:100%;height:100%;object-fit:contain}
.slot-placeholder{border-radius:50%;background:var(--tb-color-web-subtle);border:2px solid var(--web-card-border)}
.slot-placeholder[data-slot="brand.mark"]{border-radius:12px;background:var(--web-hero);border-color:var(--tb-color-web-primary)}
.slot-placeholder[data-slot="avatar.rabbit"]{background:#FFE3EF;border-color:#FF4D9A}
.slot-placeholder[data-slot="avatar.dino"]{background:#DDF7EA;border-color:#19B36B}

/* Grouped menu: always shown from 1024px; below that the Menu button opens it as a full-screen panel. */
.site-nav{display:none;padding-top:8px}.shell.menu-open .site-nav{display:block}
.shell.menu-open .rail{position:fixed;inset:0;z-index:20;overflow-y:auto}
.nav-group{margin-top:12px}
.site-nav .nav-group-title{font-family:inherit;font-size:.8125rem;line-height:1.25rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--tb-color-web-muted);margin:0 0 4px;padding:0 12px}
.site-nav ul{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.site-nav a{display:flex;align-items:center;padding:8px 12px;border-left:4px solid transparent;border-radius:var(--tb-radius-sm);color:var(--tb-color-web-ink);text-decoration:none;overflow-wrap:anywhere}
.site-nav a:hover{background:var(--tb-color-web-subtle)}
.site-nav a[aria-current=page]{background:var(--web-nav-selected);border-left-color:var(--tb-color-web-primary);font-weight:700}
@media(min-width:1024px){.menu-toggle{display:none}.site-nav{display:block}.shell.menu-open .rail{position:sticky;inset:auto;top:0;z-index:auto}}

/* Parent buttons and cards (§5.1): 3px edge, hover colour instead of a filter, 2px press. */
html[data-palette=warm] .button:hover{filter:none}
html[data-palette=warm] .button:not(.secondary):not([disabled]){box-shadow:0 3px 0 var(--web-primary-edge)}
html[data-palette=warm] .button:not(.secondary):not([disabled]):hover{background:var(--web-primary-hover);border-color:var(--web-primary-hover)}
html[data-palette=warm] .button:active{transform:translateY(2px);box-shadow:none}
html[data-palette=warm] .panel{border-color:var(--web-card-border);border-radius:var(--tb-radius-md)}

/* Status chip: icon + word on fixed color.web.status.* pairs (same on both webs). */
.status-chip{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:999px;font-size:.875rem;font-weight:600;line-height:1.5}
.status-draft{background:#EEF2F4;color:#465563}.status-review{background:#FFF1D6;color:#805200}.status-ready{background:#E3F1FB;color:#174A63}
.status-published{background:#E2F3EA;color:#126446}.status-failed{background:#FBE6E7;color:#A0272D}

/* Metric card and empty state. */
.metric-card{margin:0;padding:16px 20px;min-width:0;min-height:7.5rem;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md)}
.metric-card dt{font-size:.875rem;font-weight:600;color:var(--tb-color-web-muted)}.metric-card dd{margin:0}
.metric-value{font-family:var(--web-heading-font);font-size:2rem;line-height:2.5rem;font-weight:700;overflow-wrap:anywhere}
.metric-hint{font-size:.875rem;color:var(--tb-color-web-muted)}
.empty-state{display:grid;justify-items:center;gap:8px;padding:24px 16px;text-align:center;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md)}
.empty-state .slot{width:160px;height:160px}html[data-palette=neutral] .empty-state .slot{width:120px;height:120px}
.empty-state .slot-placeholder{border:0;border-radius:32px;background:var(--tb-color-web-subtle)}
.empty-state h2,.empty-state h3{margin:0}.empty-state p{max-width:45ch;margin:0}
@media(max-width:359px){.empty-state .slot,html[data-palette=neutral] .empty-state .slot{width:96px;height:96px}}

/* ADM-11-02/03 page patterns on the shared components. */
.metric-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,11rem),1fr));gap:12px;margin:12px 0 16px}
.hero-band{display:flex;align-items:center;gap:16px;padding:16px 20px;margin-bottom:20px;background:var(--web-hero);border-radius:var(--tb-radius-md)}
.hero-band .slot{width:96px;height:96px}.hero-band .slot-placeholder{border-radius:32px;background:var(--tb-color-web-surface)}.hero-band p{margin:0;color:var(--tb-color-web-ink);font-size:1.125rem;max-width:45ch}
@media(min-width:1024px){.hero-band .slot{width:160px;height:160px}}

/* Child picker and avatar grid: native radios kept in the tab order but drawn as chips/tiles. The chosen one has a
   3px primary ring and a bold name (never colour alone); keyboard focus draws the usual focus ring on the chip. */
.child-picker,.avatar-grid,.gift-art-picker{position:relative;border:0;margin:0 0 16px;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.child-picker legend,.avatar-grid legend,.gift-art-picker legend{width:100%;padding:0;margin-bottom:8px;font-weight:700}
.child-picker input,.avatar-grid input,.gift-art-picker input{position:absolute;opacity:0;width:1px;height:1px;min-height:0;margin:0;clip-path:inset(50%)}
.child-chip,.avatar-choice,.gift-art-choice{display:inline-flex;align-items:center;gap:8px;min-height:44px;border:2px solid var(--tb-color-web-line);background:var(--tb-color-web-surface);color:var(--tb-color-web-ink);cursor:pointer;overflow-wrap:anywhere}
.child-chip{padding:4px 16px 4px 4px;border-radius:999px}
.avatar-choice,.gift-art-choice{flex-direction:column;justify-content:center;min-width:7.5rem;padding:12px;border-radius:var(--tb-radius-md)}
.avatar-choice .slot{width:72px;height:72px}
/* ADM-11-04: 16 avatars and 20 gift pictures sit in an even grid of fixed tiles (no reflow when art loads). */
.avatar-grid,.gift-art-picker{display:grid;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr))}
.avatar-grid legend,.gift-art-picker legend{grid-column:1/-1;float:left}
.avatar-choice,.gift-art-choice{min-width:0;text-align:center}
.gift-art-choice .slot{width:64px;height:64px}
input:checked+.gift-art-choice{border:3px solid var(--tb-color-web-primary);background:var(--web-nav-selected);font-weight:700}
input:focus-visible+.gift-art-choice{outline:3px solid var(--tb-color-web-focus);outline-offset:3px}
.gift-name{display:inline-flex;align-items:center;gap:8px}.gift-name .slot{width:40px;height:40px}
input:checked+.child-chip,input:checked+.avatar-choice{border:3px solid var(--tb-color-web-primary);background:var(--web-nav-selected);font-weight:700}
input:focus-visible+.child-chip,input:focus-visible+.avatar-choice{outline:3px solid var(--tb-color-web-focus);outline-offset:3px}

/* Child cards (profiles, settings): avatar beside the name and facts; one column on phones. */
.profile-cards,.child-cards{list-style:none;margin:0;padding:0;display:grid;gap:16px}
.profile-card,.child-card{display:flex;gap:16px;align-items:flex-start;min-width:0;padding:24px;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md);overflow-wrap:anywhere}
.profile-card>.slot{width:72px;height:72px}.profile-card-body{flex:1;min-width:0}.profile-card h3{margin:0 0 8px}
.profile-facts{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 12px;margin:0}.profile-facts dt{font-weight:600;color:var(--tb-color-web-muted)}.profile-facts dd{margin:0}
.child-card{align-items:center;flex-wrap:wrap}.child-card .action-row{margin-top:0}
/* Periodic papers (BE-13-02): one bordered card per grade × test type, its "Giao đề" button inside it. */
.periodic-papers{display:grid;gap:12px;margin-top:16px}
.periodic-paper{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;min-width:0;padding:16px 20px;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md)}
.periodic-paper-text{min-width:0;overflow-wrap:anywhere}.periodic-paper-text p{margin:4px 0 0}
.tech-details{margin-top:16px}.tech-details summary{display:flex;align-items:center;min-height:44px;cursor:pointer;color:var(--tb-color-web-muted)}
@media(min-width:1024px){.profile-cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:359px){.profile-card,.child-card{flex-direction:column;padding:16px}}

/* Content-block choice (U-31, R34): each block is a tile with a real checkbox; ticked tiles are ringed and bold. */
.profile-blocks{border:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,10rem),1fr));gap:8px}
.profile-blocks legend,.profile-blocks small{grid-column:1/-1}
.profile-block{display:flex;align-items:center;gap:8px;min-height:44px;padding:8px 12px;border:2px solid var(--tb-color-web-line);border-radius:var(--tb-radius-sm);background:var(--tb-color-web-surface);cursor:pointer}
.profile-block input{flex:none;width:20px;height:20px;min-height:0}
.profile-block:has(input:checked){border-color:var(--tb-color-web-primary);font-weight:700}

/* Tables: header row stays visible while the labelled region scrolls (ADM-11-03). Below 768px a `.table-cards`
   table shows each row as a card, each cell named by its column (labelCells), so phones never scroll sideways. */
.table-scroll{max-height:70vh;overflow:auto}.table-scroll th{position:sticky;top:0;z-index:1}
@media(max-width:767px){
  .table-scroll:has(.table-cards){max-height:none;overflow:visible;border:0}
  .table-cards{min-width:0;background:transparent}
  .table-cards thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  .table-cards tr{display:block;margin:0 0 12px;padding:8px 16px;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md)}
  .table-cards td{display:grid;grid-template-columns:minmax(0,8rem) minmax(0,1fr);gap:8px;padding:6px 0;border-bottom:0;overflow-wrap:anywhere}
  .table-cards td[data-label]::before{content:attr(data-label);font-weight:600;color:var(--tb-color-web-muted)}
}

/* Admin stays compact and calm: tighter cards and cells, chips spaced from the line below. */
html[data-palette=neutral] .panel{padding:16px}html[data-palette=neutral] th,html[data-palette=neutral] td{padding:8px 12px}
.panel>.status-chip,li>.status-chip,section>.status-chip{margin-bottom:8px}td>.status-chip{white-space:nowrap}

/* ADM-11-05 loading: skeleton blocks keep the final outline (fixed sizes per shape, page-skeleton.ts); the shimmer runs
   only when the reader allows motion. Loading never borrows the error banner or the empty-state style. */
.page-skeleton,.loading-state{display:grid;gap:16px;min-height:12rem;margin-bottom:16px}
.sk-status{margin:0;font-size:.875rem;color:var(--tb-color-web-muted)}
.sk-shape{display:grid;gap:8px}.sk{display:block;min-width:0;background:var(--tb-color-web-subtle);border-radius:var(--tb-radius-sm)}
[data-shape=hero]{height:160px}[data-shape=hero] .sk{height:100%;background:var(--web-hero);border-radius:var(--tb-radius-md)}
[data-shape=chips]{display:flex;flex-wrap:wrap;height:48px;overflow:hidden}[data-shape=chips] .sk{width:8rem;height:48px;border-radius:999px}
[data-shape=metrics]{grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));min-height:7.5rem}[data-shape=metrics] .sk{height:7.5rem;border-radius:var(--tb-radius-md)}
[data-shape=card]{min-height:11rem;padding:20px;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md)}[data-shape=card] .sk{height:1rem}[data-shape=card] .sk:first-child{width:40%;height:1.75rem}
[data-shape=cards]{grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));min-height:8rem}[data-shape=cards] .sk{height:8rem;border-radius:var(--tb-radius-md)}
[data-shape=table]{min-height:18rem}[data-shape=table] .sk{height:2.5rem}
[data-shape=chart]{height:16rem}[data-shape=chart] .sk{height:100%;border-radius:var(--tb-radius-md)}
[data-shape=list]{min-height:16rem}[data-shape=list] .sk{height:3.5rem;border-radius:var(--tb-radius-md)}
@media (prefers-reduced-motion:no-preference){.sk{animation:sk-pulse 1.6s ease-in-out infinite}}
@keyframes sk-pulse{50%{opacity:.55}}

/* ADM-11-06 charts (svg-charts.ts): plain SVG sized by its viewBox; numbers for screen readers in a hidden table. */
.chart{margin:12px 0}.chart svg{display:block;width:100%;max-width:32rem;height:auto;overflow:visible}
.chart-ratio svg{max-width:16rem}.chart-label{font-size:.875rem;color:var(--tb-color-web-muted);margin-bottom:4px}
.chart-mark{fill:#B33F12}.chart-track{fill:#FDEEDF}.chart-axis{fill:var(--tb-color-web-line)}
.chart-value,.chart-tick{font:600 11px 'Lexend',system-ui,sans-serif;fill:var(--tb-color-web-ink);text-anchor:middle}.chart .start{text-anchor:start}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.empty-state.compact{padding:16px;gap:4px;margin:8px 0}.empty-state.compact .slot{width:96px;height:96px}.empty-state.compact p{margin:0}
.chart-details{margin-top:8px}.chart-details summary{cursor:pointer;font-weight:600;color:var(--tb-color-web-primary);min-height:44px;display:flex;align-items:center}

/* ADM-14-01: signed-out parent frame — one centred brand card on the warm hero tone; no rail, no menu. */
.signed-out{min-height:100vh;display:grid;place-items:center;padding:32px 16px;background:linear-gradient(180deg,var(--web-hero),var(--tb-color-web-canvas))}
.signed-out-card{width:100%;max-width:480px;display:grid;gap:16px;padding:32px 28px;background:var(--tb-color-web-surface);border:1px solid var(--web-card-border);border-radius:var(--tb-radius-md);box-shadow:0 12px 32px #2b211c1a}
.signed-out-head{display:grid;justify-items:center;gap:8px;text-align:center}.signed-out-head .brand-head{justify-content:center}
.signed-out-head h1{margin:8px 0 0}.signed-out-head p{margin:0;max-width:40ch}
.signed-out-card .panel{padding:0;border:0;background:none}.signed-out-card .panel h2{margin-top:0}.signed-out-card .banner{margin:0}
.signed-out-card form .button{width:100%;margin-top:8px}
@media(max-width:390px){.signed-out{place-items:start center;padding:16px 12px}.signed-out-card{padding:24px 16px}}
/* R51: Google sign-in is a full-width secondary button with the G mark, apart from the primary "Gửi mã". */
.google-button{width:100%;gap:10px;margin-bottom:8px}.google-button svg{width:20px;height:20px;flex:none}
/* R51 (ADM-14-06): long hh_… ids wrap at 390 px; the licence card sits apart from the household links. */
.household-list h3{overflow-wrap:anywhere}
.premium-card{margin:16px 0;padding-top:16px;border-top:1px solid var(--web-card-border)}.premium-card h4{margin:0 0 8px}.premium-licence .status-chip{margin-bottom:8px}
