/* ============================================================
   Learn on Past Exam Papers — shared platform chrome
   ------------------------------------------------------------
   ONE stylesheet, loaded by the landing page AND by every built
   component, so the masthead is identical everywhere by
   construction rather than by convention.

   Layout contract
   ---------------
     <header class="pxp-bar">      platform masthead   (sticky, top:0)
     [ component's own header ]    section nav         (sticky, under the masthead)
     [ component content ]

   Sections below:
     1. Design tokens
     2. Platform masthead
     3. Shared "section nav" look for a component's own header
     4. Per-preset normalisation (scoped to data-platform-preset)
     5. Responsive + print

   IMPORTANT for future component swaps
   ------------------------------------
   Section 4 is the only place that knows a component's internal class
   names, and every rule there is cosmetic. If an upgraded component
   renames a class, the rule stops matching and that component simply
   falls back to its own upstream header — the site keeps working.
   Update the `header` selectors in platform.config.json and the
   matching block here; never edit the component itself.
   ============================================================ */

/* ---------- 1. Design tokens ---------- */
:root {
  --pxp-ink: #12385b;
  --pxp-ink-soft: #526b7f;
  --pxp-paper: #f7faf8;
  --pxp-surface: #ffffff;
  --pxp-line: #d9e3e8;
  --pxp-line-soft: rgba(18, 56, 91, 0.11);
  --pxp-green: #2f8b68;
  --pxp-green-soft: #e3f3ec;
  --pxp-blue: #2c76b7;
  --pxp-blue-soft: #e4f0fa;
  --pxp-gold: #b97816;
  --pxp-gold-soft: #fff1d9;
  --pxp-purple: #6b4fa8;
  --pxp-purple-soft: #eee9f9;

  --pxp-font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --pxp-rail: 1120px;
  --pxp-radius: 9px;

  /* Measured at runtime by component-shell.js; these are the fallbacks
     used before the script runs and if JavaScript is unavailable. */
  --pxp-bar-h: 60px;
  --pxp-sub-h: 56px;

  /* ---- PUBLIC CONTRACT FOR COMPONENTS ----
     How much fixed chrome the platform has placed above the component.
     A component that anchors anything to the top of the viewport — a
     sticky header, a full-screen overlay, a scroll-margin-top — should
     write `var(--app-offset-top, 0px)` instead of a hard-coded 0 or a
     magic number. Standalone the variable is undefined and the
     fallback of 0px applies, so the component is unchanged on its own;
     embedded here it lines up automatically and this stylesheet needs
     no per-component rule for it.
     It tracks --pxp-bar-h, which is re-measured whenever the bar
     resizes, so it is correct at every breakpoint. */
  --app-offset-top: var(--pxp-bar-h);
}

/* ---------- 2. Platform masthead ----------
   z-index 45 is deliberate: above every component's own header
   (normalised to 40) and page content, but BELOW their dialogs, popup
   menus and overlays (60–400 across the four components) so a modal
   still owns the screen. */
.pxp-bar {
  position: sticky;
  top: 0;
  z-index: 45;
  /* see .pxp-bar.pxp-menu-open below */
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--pxp-line-soft);
  background: var(--pxp-surface);
  color: var(--pxp-ink);
  font-family: var(--pxp-font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.pxp-bar *,
.pxp-bar *::before,
.pxp-bar *::after { box-sizing: border-box; }

/* While the area switcher is open the whole bar is lifted above every
   component overlay. The dropdown hangs BELOW the bar, into territory owned
   by things like the Study Planner's full-screen first-run wizard (z-index
   100) — at the bar's resting z-index of 45 the menu rendered but was not
   clickable. The class is added by component-shell.js only while the menu is
   open, so at rest a component's modals still own the screen as intended.
   The menu cannot simply raise its own z-index: .pxp-bar establishes the
   stacking context, so a descendant can never escape it. */
.pxp-bar.pxp-menu-open { z-index: 1000; }

/* THE RAIL. Every component's header and page content is normalised to
   this same box below, so the brand, the section nav and the content all
   share one left edge. */
.pxp-bar-inner {
  max-width: var(--pxp-rail);
  margin-inline: auto;
  padding-inline: 20px;
  min-height: 60px;
  display: flex;
  align-items: center;
  gap: 14px;
}

/* brand lockup — identical on the landing page and inside every component */
.pxp-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: none;
  color: var(--pxp-ink);
  text-decoration: none;
}
.pxp-brand:focus-visible {
  outline: 3px solid var(--pxp-green-soft);
  outline-offset: 3px;
  border-radius: var(--pxp-radius);
}
.pxp-brand-mark {
  width: 40px;
  height: 40px;
  flex: none;
  object-fit: contain;
  display: block;
}
.pxp-brand-copy {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
}
.pxp-brand-copy strong {
  font-size: 0.94rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.pxp-brand-copy span {
  margin-top: 4px;
  color: var(--pxp-green);
  font-size: 0.62rem;
  font-weight: 850;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* current-area switcher */
.pxp-switch { position: relative; flex: 0 1 auto; min-width: 0; }
.pxp-switch-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  margin: 0;
  padding: 7px 10px 7px 11px;
  border: 1px solid var(--pxp-line);
  border-radius: 999px;
  background: var(--pxp-surface);
  color: var(--pxp-ink);
  font-family: inherit;
  font-size: 0.84rem;
  font-weight: 730;
  line-height: 1.2;
  cursor: pointer;
}
.pxp-switch-btn:hover { border-color: color-mix(in srgb, var(--pxp-ink) 26%, white); }
.pxp-switch-btn:focus-visible { outline: 3px solid var(--pxp-green-soft); outline-offset: 2px; }
.pxp-dot {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--pxp-accent, var(--pxp-ink-soft));
}
.pxp-switch-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pxp-caret { width: 11px; height: 11px; flex: none; opacity: 0.55; }
.pxp-switch-btn[aria-expanded="true"] .pxp-caret { transform: rotate(180deg); }

.pxp-switch-menu {
  position: absolute;
  top: calc(100% + 7px);
  left: 0;
  z-index: 20;
  min-width: 258px;
  padding: 7px;
  border: 1px solid var(--pxp-line);
  border-radius: 13px;
  background: var(--pxp-surface);
  box-shadow: 0 14px 38px rgba(18, 56, 91, 0.16);
}
.pxp-switch-menu[hidden] { display: none; }
.pxp-switch-group {
  margin: 7px 9px 5px;
  color: var(--pxp-ink-soft);
  font-size: 0.6rem;
  font-weight: 850;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.pxp-switch-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 9px;
  border-radius: var(--pxp-radius);
  color: var(--pxp-ink);
  font-size: 0.86rem;
  font-weight: 640;
  text-decoration: none;
}
.pxp-switch-item:hover,
.pxp-switch-item:focus-visible { background: var(--pxp-paper); outline: none; }
.pxp-switch-item small {
  margin-left: auto;
  color: var(--pxp-ink-soft);
  font-size: 0.66rem;
  font-weight: 700;
}
.pxp-switch-item[aria-current="page"] { background: var(--pxp-paper); }
.pxp-switch-item[aria-current="page"] small { color: var(--pxp-accent, var(--pxp-green)); }
/* site links (privacy, terms) — no accent dot, lighter weight */
.pxp-switch-plain {
  padding-left: 26px;
  color: var(--pxp-ink-soft);
  font-weight: 600;
}
.pxp-switch-plain:hover { color: var(--pxp-ink); }

/* accents, shared with the landing cards */
[data-accent="green"]  { --pxp-accent: var(--pxp-green);  --pxp-accent-soft: var(--pxp-green-soft); }
[data-accent="blue"]   { --pxp-accent: var(--pxp-blue);   --pxp-accent-soft: var(--pxp-blue-soft); }
[data-accent="gold"]   { --pxp-accent: var(--pxp-gold);   --pxp-accent-soft: var(--pxp-gold-soft); }
[data-accent="purple"] { --pxp-accent: var(--pxp-purple); --pxp-accent-soft: var(--pxp-purple-soft); }

/* right-hand site links */
.pxp-links {
  margin-left: auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  flex: none;
}
.pxp-links a {
  padding: 8px 11px;
  border-radius: var(--pxp-radius);
  color: var(--pxp-ink-soft);
  font-size: 0.84rem;
  font-weight: 720;
  text-decoration: none;
  white-space: nowrap;
}
.pxp-links a:hover,
.pxp-links a:focus-visible { background: var(--pxp-paper); color: var(--pxp-ink); }
.pxp-links .pxp-papers { background: var(--pxp-ink); color: #fff; }
.pxp-links .pxp-papers:hover,
.pxp-links .pxp-papers:focus-visible { background: var(--pxp-green); color: #fff; }

/* ---------- 3. Shared "section nav" look ----------
   The rule below is GENERATED at build time from the `header.selector`
   values in platform.config.json, so every component's own header gets
   the same treatment without this file listing them by hand. Look in
   dist/assets/component-shell.css to see the expanded version. */
/* generated from platform.config.json — each component's own header, restyled as the section nav */
html[data-platform-preset="delphi-ide"] .topbar,
html[data-platform-preset="vite-subject"] .site-header,
html[data-platform-preset="planner"] .app-header {
  position: sticky;
  top: var(--pxp-bar-h);
  z-index: 40;
  background: color-mix(in srgb, var(--pxp-paper) 92%, transparent);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
  border-bottom: 1px solid var(--pxp-line-soft);
  box-shadow: none;
  margin-bottom: 0;
}


/* ---------- 4. Per-component normalisation ---------- */

/* --- 4a. Information Technology (full-height IDE shell) ---
   This component is an app shell: html/body are height:100%, #app is a
   flex column and the panes scroll internally. Adding a masthead above
   it would push it 60px past the viewport, so the shell is given the
   remaining height instead of the whole viewport. */
html[data-platform-preset="delphi-ide"] #app {
  height: calc(100vh - var(--pxp-bar-h));
  height: calc(100dvh - var(--pxp-bar-h));
}
html[data-platform-preset="delphi-ide"] .topbar {
  height: auto;
  min-height: 52px;
  /* full-bleed band, content on the shared rail */
  padding-inline: max(20px, calc((100% - var(--pxp-rail)) / 2 + 20px));
  color: var(--pxp-ink);
  gap: 10px;
}
/* the IT content rail is 1080px upstream; match the platform's 1120px */
html[data-platform-preset="delphi-ide"] .page-inner {
  max-width: var(--pxp-rail);
  padding-inline: 20px;
}
html[data-platform-preset="delphi-ide"] .topbar > .logo { display: none; }
html[data-platform-preset="delphi-ide"] .topnav {
  margin-left: 0;
  flex-wrap: wrap;
  gap: 2px;
}
html[data-platform-preset="delphi-ide"] .topnav button {
  color: var(--pxp-ink-soft);
  font-family: var(--pxp-font);
  font-size: 0.86rem;
  font-weight: 680;
  padding: 7px 11px;
  border-radius: var(--pxp-radius);
}
html[data-platform-preset="delphi-ide"] .topnav button:hover {
  background: var(--pxp-surface);
  color: var(--pxp-ink);
}
html[data-platform-preset="delphi-ide"] .topnav button.active {
  background: var(--pxp-ink);
  color: #fff;
  font-weight: 750;
}
html[data-platform-preset="delphi-ide"] .progress-chip {
  background: var(--pxp-surface);
  border: 1px solid var(--pxp-line);
  color: var(--pxp-ink-soft);
  font-family: var(--pxp-font);
  font-size: 0.78rem;
  font-weight: 650;
}
html[data-platform-preset="delphi-ide"] .progress-chip b { color: var(--pxp-ink); }
/* the forced right-hand pane is pinned below both bars */
html[data-platform-preset="delphi-ide"] .wpane.right-pane.forced {
  top: calc(102px + var(--pxp-bar-h));
}

/* --- 4b. Mathematics and Physical Sciences (shared upstream shell) --- */
html[data-platform-preset="vite-subject"] .site-header-inner {
  max-width: var(--pxp-rail);
  padding: 8px 20px;
  min-height: 52px;
  gap: 14px;
}
html[data-platform-preset="vite-subject"] .site-header .brand { display: none; }
html[data-platform-preset="vite-subject"] .site-nav { margin-left: 0; gap: 2px; }
html[data-platform-preset="vite-subject"] .site-nav a {
  padding: 7px 11px;
  border-radius: var(--pxp-radius);
  color: var(--pxp-ink-soft);
  font-family: var(--pxp-font);
  font-size: 0.86rem;
  font-weight: 680;
}
html[data-platform-preset="vite-subject"] .site-nav a:hover {
  background: var(--pxp-surface);
  color: var(--pxp-ink);
}
html[data-platform-preset="vite-subject"] .site-nav a.active {
  background: var(--pxp-ink);
  color: #fff;
  font-weight: 750;
}
html[data-platform-preset="vite-subject"] .header-chip {
  margin-left: auto;
  background: var(--pxp-surface);
  border: 1px solid var(--pxp-line);
  border-radius: 999px;
  padding: 5px 12px;
  color: var(--pxp-ink-soft);
  font-family: var(--pxp-font);
  font-size: 0.78rem;
  font-weight: 650;
}
/* upstream scroll offsets assume a ~56px header; add the masthead */
html[data-platform-preset="vite-subject"] .list-meta { scroll-margin-top: calc(76px + var(--pxp-bar-h)); }
html[data-platform-preset="vite-subject"] .note-card { scroll-margin-top: calc(80px + var(--pxp-bar-h)); }
/* the in-app skip link must clear the masthead when focused */
html[data-platform-preset="vite-subject"] .skip-link:focus { top: calc(var(--pxp-bar-h) + 6px); }
html[data-platform-preset="vite-subject"] .main { max-width: var(--pxp-rail); }

/* --- 4c. Study Planner --- */
html[data-platform-preset="planner"] .app-header { border-bottom: 0; }
html[data-platform-preset="planner"] .head-inner {
  max-width: var(--pxp-rail);
  min-height: 52px;
  padding: 8px 20px;
}
html[data-platform-preset="planner"] .app-header .brand { display: none; }
html[data-platform-preset="planner"] main { max-width: var(--pxp-rail); }
/* the first-run wizard is a full-screen fixed overlay; keep the platform
   masthead visible above it instead of letting it clip the wizard */
html[data-platform-preset="planner"] #onboard { top: var(--pxp-bar-h); }

/* Above 720px the tab strip becomes the section nav and sticks under the
   masthead. Below 720px the planner turns .tabs into its own fixed
   bottom bar — a deliberate mobile design — so nothing here touches it. */
@media (min-width: 721px) {
  html[data-platform-preset="planner"] .tabs {
    position: sticky;
    top: calc(var(--pxp-bar-h) + var(--pxp-sub-h));
    z-index: 39;
    max-width: none;
    margin: 0;
    padding: 6px max(20px, calc((100% - var(--pxp-rail)) / 2 + 20px)) 8px;
    background: color-mix(in srgb, var(--pxp-paper) 92%, transparent);
    -webkit-backdrop-filter: blur(9px);
    backdrop-filter: blur(9px);
    border-bottom: 1px solid var(--pxp-line-soft);
  }
  html[data-platform-preset="planner"] .tab {
    font-family: var(--pxp-font);
    font-size: 0.84rem;
    font-weight: 680;
    border-radius: var(--pxp-radius);
  }
  html[data-platform-preset="planner"] .tab[aria-selected="true"] {
    background: var(--pxp-ink);
    color: #fff;
    border-color: var(--pxp-ink);
    font-weight: 750;
  }
}
/* the planner is the one component with a dark mode; keep the platform
   chrome legible there rather than forcing a white bar onto a dark page */
@media (prefers-color-scheme: dark) {
  html[data-platform-preset="planner"] .pxp-bar,
  html[data-platform-preset="planner"] .pxp-sub {
    background: #14161a;
    color: #f2f2f0;
    border-bottom-color: rgba(255, 255, 255, 0.12);
  }
  html[data-platform-preset="planner"] .pxp-brand,
  html[data-platform-preset="planner"] .pxp-switch-btn { color: #f2f2f0; }
  html[data-platform-preset="planner"] .pxp-switch-btn,
  html[data-platform-preset="planner"] .pxp-switch-menu {
    background: #1c1f24;
    border-color: rgba(255, 255, 255, 0.16);
  }
  html[data-platform-preset="planner"] .pxp-switch-item { color: #f2f2f0; }
  html[data-platform-preset="planner"] .pxp-switch-item:hover,
  html[data-platform-preset="planner"] .pxp-switch-item[aria-current="page"] { background: #262a31; }
  html[data-platform-preset="planner"] .pxp-links a { color: #b9bec7; }
  html[data-platform-preset="planner"] .pxp-links a:hover { background: #262a31; color: #fff; }
  html[data-platform-preset="planner"] .pxp-links .pxp-papers { background: #f2f2f0; color: #14161a; }
  html[data-platform-preset="planner"] .pxp-links .pxp-papers:hover { background: #fff; color: #14161a; }
  html[data-platform-preset="planner"] .tab[aria-selected="true"] {
    background: #f2f2f0;
    color: #14161a;
    border-color: #f2f2f0;
  }
}
@media (prefers-color-scheme: dark) and (min-width: 721px) {
  html[data-platform-preset="planner"] .tabs {
    background: rgba(20, 22, 26, 0.92);
    border-bottom-color: rgba(255, 255, 255, 0.12);
  }
}

/* ---------- 4d. Hidden upstream elements ----------
   GENERATED from the `hide` lists in platform.config.json. Use that
   config rather than adding rules here, so the reason for each
   suppression travels with it and survives a component swap. */
/* generated from platform.config.json — upstream elements hidden on this site */
  /* upstream beta notice — not shown on this site */
html[data-platform-component="mathematics"] .beta-banner { display: none !important; }
  /* first-run wizard's own brand lockup — the masthead already carries the brand */
html[data-platform-component="study-planner"] #onboard .ob-logo { display: none !important; }


/* ---------- 5. Responsive + print ---------- */
@media (max-width: 900px) {
  .pxp-bar-inner { padding-inline: 14px; gap: 10px; }
  .pxp-links a:not(.pxp-papers) { display: none; }
}

/* Below 720px the component navs are given a single scrollable row rather
   than being allowed to wrap into a second and third line under the
   masthead. Matches the breakpoint the components themselves use. */
@media (max-width: 720px) {
  html[data-platform-preset="vite-subject"] .site-nav,
  html[data-platform-preset="delphi-ide"] .topnav {
    order: 0;
    width: auto;
    flex: 1 1 auto;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  html[data-platform-preset="vite-subject"] .site-nav::-webkit-scrollbar,
  html[data-platform-preset="delphi-ide"] .topnav::-webkit-scrollbar { display: none; }
  html[data-platform-preset="vite-subject"] .site-nav a,
  html[data-platform-preset="delphi-ide"] .topnav button { white-space: nowrap; }
  html[data-platform-preset="vite-subject"] .header-chip,
  html[data-platform-preset="delphi-ide"] .progress-chip {
    order: 1;
    flex: none;
    margin-left: 10px;
  }
  html[data-platform-preset="vite-subject"] .site-header-inner { flex-wrap: nowrap; }
}

@media (max-width: 640px) {
  :root { --pxp-bar-h: 54px; }
  .pxp-bar-inner { min-height: 54px; }
  .pxp-brand-mark { width: 34px; height: 34px; }
  /* the wordmark is dropped so the area switcher keeps a readable label —
     the logo mark still links home */
  .pxp-brand-copy { display: none; }
  .pxp-switch { flex: 1 1 auto; }
  .pxp-switch-btn { width: 100%; padding: 6px 9px; font-size: 0.79rem; }
  .pxp-switch-menu { min-width: min(280px, calc(100vw - 24px)); }
  .pxp-links a { padding: 7px 9px; font-size: 0.79rem; }

  /* the progress chips duplicate a figure each component already shows on
     its own home screen; on a phone the nav needs the whole row */
  html[data-platform-preset="vite-subject"] .header-chip,
  html[data-platform-preset="delphi-ide"] .progress-chip { display: none; }

  /* one sticky bar is enough on a phone — the component headers, which
     wrap to two rows at this width, go back to normal flow. The list of
     selectors is generated from platform.config.json. */
  html[data-platform-preset="delphi-ide"] .topbar,
  html[data-platform-preset="vite-subject"] .site-header,
  html[data-platform-preset="planner"] .app-header { position: static; }
}

@media print {
  .pxp-bar { display: none !important; }
}
