/* ==========================================================================
   band9-shell.css — Band 9 PTE shared design tokens + shell
   --------------------------------------------------------------------------
   Token values are taken verbatim from speaking.html's :root block (the most
   recent module page, built against this site) and are the source of truth.
   The additive scale tokens (radii / spacing / font size / elevation) are
   named after values already in use on writing.html, reading.html and
   listening.html, so adopting them is a zero-visual-change edit.

   Layers, in cascade order:
     1. Tokens  :root custom properties
     2. Base    reset, typography defaults, accessibility primitives
     3. Shell   header/top bar, container width, card, button, ad container,
                inline role="alert" bar, footer

   Consumers link this BEFORE their page <style> block, so a page-specific
   rule wins on equal specificity and the page keeps its own specifics.
   Nothing here renames a class the runner JS writes: the alert bar carries
   both the canonical .page-alert name and the .inline-alert alias that
   writing.html's showPageAlert() emits.
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- */
:root{
  --lh-base:1.6;
  /* colours — verbatim from speaking.html :root, do not re-value */
  --navy:#1e3c72;
  --navy2:#2a5298;
  --ink:#0f1d3a;
  --text:#1f2937;
  --muted:#566479;
  --line:#e3e8f0;
  --bg:#f3f6fb;
  --blue:#1f6fa5;
  --green:#1e8449;
  --red:#c0392b;
  /* accent used by the writing / reading / listening skill pages */
  --accent:#667eea;
  --accent2:#764ba2;
  /* radii */
  --r:14px;      /* speaking.html default card radius */
  --r-sm:8px;
  --r-md:10px;
  --r-lg:12px;
  --r-xl:16px;
  --r-2xl:20px;
  /* spacing */
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px;
  --sp-5:20px; --sp-6:30px; --sp-7:40px;
  /* font scale */
  --font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Inter,system-ui,sans-serif;
  --fs-xs:12px; --fs-sm:13px; --fs-md:15px; --fs-base:16px;
  --fs-lg:20px; --fs-xl:26px; --fs-2xl:32px;
  /* elevation */
  --shadow-card:0 6px 22px rgba(15,29,58,.07);
  --shadow-strong:0 10px 40px rgba(0,0,0,.3);
  /* sticky-header / anchor offset */
  --anchor-h:0px;
}

/* 2. Base ------------------------------------------------------------------ */
*{box-sizing:border-box;margin:0;padding:0}
/* scroll-behavior and scroll-padding-top are deliberately NOT set here: a
   smooth-scroll base changes the semantics of window.scrollTo(0,0), which the
   module runners call on exit, and a sticky-header offset would mis-land
   anchors on the pages whose header is not sticky. Pages that want them
   declare them themselves (speaking.html already does). */
html{-webkit-text-size-adjust:100%}
body{font-family:var(--font-sans);font-size:var(--fs-base);line-height:var(--lh-base);color:var(--text);background:var(--bg)}
img{max-width:100%;height:auto}
a{color:var(--blue)}
button{font:inherit;color:inherit;cursor:pointer}
button:disabled{cursor:not-allowed}
:focus-visible{outline:3px solid #ffbf47;outline-offset:2px}
[hidden]{display:none!important}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{transition:none!important;animation:none!important}}

/* 3. Shell components ------------------------------------------------------ */

/* container width */
.wrap{max-width:1120px;margin:0 auto;padding:0 20px}

/* header / top bar */
.top{position:sticky;top:0;z-index:20;background:var(--navy);box-shadow:0 2px 12px rgba(0,0,0,.18)}
.top .wrap{display:flex;align-items:center;justify-content:space-between;gap:12px;height:56px}
.top .wrap>a{flex:none}
.top img{height:34px;width:auto;display:block;flex:none}
.top nav{display:flex;gap:2px;overflow-x:auto;scrollbar-width:none}
.top nav a{flex:none;color:#fff;text-decoration:none;padding:11px 12px;border-radius:8px;font-size:14px;font-weight:500}
.top nav a:hover,.top nav a[aria-current]{background:rgba(255,255,255,.16)}

/* card */
.card{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:20px;box-shadow:var(--shadow-card);min-width:0}
@media(min-width:700px){.card{padding:28px}}

/* button */
.btn{min-height:48px;padding:0 22px;border:0;border-radius:999px;background:var(--navy);color:#fff;font:inherit;font-weight:700}
.btn:hover:not(:disabled){background:var(--navy2)}
.btn.ghost{background:#fff;color:var(--navy);border:1.5px solid var(--navy)}
.btn.small{min-height:44px;padding:0 16px;font-size:14px}
.btn:disabled{opacity:.45}

/* ad container: reserved height, label, hide when unfilled */
.ad{text-align:center;margin:28px 0;min-height:280px;overflow:hidden}
.ad-l{display:block;font-size:12px;color:var(--muted);margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px}
.ad ins{display:block;min-height:250px}
.ad ins[data-ad-status=unfilled]{display:none}
.side .ad{margin:0;min-height:620px}
.side .ad ins{width:300px;min-height:600px}

/* inline, non-blocking replacement for alert(): role="alert" bar */
.page-alert,.inline-alert{
  padding:14px 18px;
  border-radius:var(--r-md);
  font-size:var(--fs-md);
  line-height:1.5;
  font-weight:600;
  position:sticky;
  top:0;
  z-index:2000;
  box-shadow:0 6px 18px rgba(0,0,0,.25);
}
.page-alert[hidden],.inline-alert[hidden]{display:none}
.page-alert-error,.inline-alert-error{
  background:#fef2f2;
  border:1px solid #fecaca;
  border-left:5px solid #dc2626;
  color:#991b1b;
}
.page-alert-success,.inline-alert-success{
  background:#f0fdf4;
  border:1px solid #bbf7d0;
  border-left:5px solid #16a34a;
  color:#166534;
}

/* footer */
footer{background:var(--navy);color:#fff;text-align:center;padding:26px 20px;font-size:14px}
footer a{padding:8px 10px;color:rgba(255,255,255,.85);text-decoration:none;display:inline-block}


/* ---------------------------------------------------------------------------
   4. Mobile navigation: hamburger
   Same control as index.html (3 bars, rotate-into-X). The header is NAVY, so
   the bars are white; the dropdown panel is white, so the links inside it are
   dark. (Both were got wrong first time round: navy bars on a navy header were
   invisible, and white links on a white panel were too.)
   The strip it replaces used overflow-x:auto with scrollbar-width:none, which
   hid the off-screen links with no affordance that anything scrolled.
--------------------------------------------------------------------------- */
.top .hamburger { display:none; flex-direction:column; justify-content:center; gap:5px;
  cursor:pointer; background:none; border:0; padding:8px; margin-left:auto; }
.top .hamburger span { display:block; width:25px; height:3px; background:#fff;
  border-radius:3px; transition:transform .3s, opacity .3s; }
.top .hamburger.active span:nth-child(1) { transform:rotate(45deg) translate(6px, 6px); }
.top .hamburger.active span:nth-child(2) { opacity:0; }
.top .hamburger.active span:nth-child(3) { transform:rotate(-45deg) translate(7px, -7px); }

@media (max-width:700px) {
  .top { position:relative; }
  .top .hamburger { display:flex; }
  .top nav { display:none; position:absolute; top:100%; left:0; right:0; z-index:60;
    background:#fff; flex-direction:column; gap:0; padding:8px; overflow:visible;
    border-top:1px solid var(--line); box-shadow:0 10px 30px rgba(15,35,60,.14); }
  .top nav.active { display:flex; }
  .top nav a { width:100%; text-align:left; padding:14px 16px; border-radius:10px;
    font-size:15px; color:var(--ink); }
  .top nav a:hover, .top nav a[aria-current] { background:var(--bg); }
}

/* Sourced per-task spec line (Pearson's published figures) */
.spec { margin:8px 0 12px; padding:8px 12px; background:var(--bg); border-left:3px solid var(--blue);
  border-radius:0 8px 8px 0; font-size:13px; line-height:1.5; color:var(--muted,#5b6472); }
.spec strong { color:var(--ink); }
