/* Shared application shell -- styles for public/app-shell.js.
 * Entirely namespaced under `.raise-shell-*` / `#raise-shell-root` --
 * never the generic `.header`, which several target pages already use
 * for their own page-title block.
 *
 * All 13 target pages link public/css/theme.css (added for the shell
 * wordmark's shared display typeface -- see below), but every token
 * used in this file still carries an explicit literal fallback rather
 * than assuming theme.css is present, since this file must also keep
 * working correctly if a future page adopts the shell without linking
 * theme.css. Falls back to RAISE's canonical ink/marker/paper values
 * from theme.css directly.
 *
 * --raise-shell-accent / --raise-shell-accent-secondary are set by
 * public/branding.js (school colour, or the RAISE defaults) -- this
 * file only ever reads them, never sets a colour literal that bypasses
 * that single source of truth. The sidebar and mobile top bar's own
 * background reads --raise-shell-accent directly, so by default (no
 * school branding) they render RAISE's own navy; once complete school
 * branding is active, the school's primary/secondary colours take
 * over there instead -- reverting entirely to navy-and-pink the
 * moment branding becomes incomplete, inactive or invalid again.
 *
 * The RAISE wordmark (.raise-shell-brand-mark) is the one deliberate
 * exception: its own background/text colours are FIXED literals,
 * never --raise-shell-accent/-secondary, so it stays legible sitting
 * on top of whatever colour the sidebar/top bar is currently showing
 * -- RAISE's own navy or an arbitrary school colour alike. Its
 * treatment is: a rectangular "RAISE" badge in RAISE's own dark ink
 * (#1B2340 -- RAISE_DEFAULTS.ink) with lettering in
 * --color-marker-on-dark (#E4738A -- theme.css's own established
 * token for pink-on-navy text; deliberately lighter/less saturated
 * than ordinary marker pink, which clashes on a dark background);
 * "Learning" also in that same dark ink. BOTH the badge and "Learning"
 * are set in the site-wide display typeface via theme.css's
 * --font-display token (Lora, with a literal 'Lora', Georgia, serif
 * fallback in case theme.css isn't loaded) -- the same typeface
 * Production's own live-site wordmark uses, on both pieces: the public
 * .nav-brand-badge sets no font-family of its own and simply inherits
 * Lora from its parent .nav-brand, so .raise-shell-brand-badge reads
 * var(--font-display, ...) directly to match that inherited result
 * (the shell's badge and word are sibling elements, not nested, so
 * inheritance alone can't do it here -- it has to be explicit). The
 * badge carries no letter-spacing either, again matching
 * .nav-brand-badge's own unset (default, non-expanded) spacing -- an
 * earlier, since-corrected version of this badge used
 * --raise-shell-font (Work Sans/DM Sans) with expanded 0.04em tracking,
 * a treatment suited to a small bold sans-serif label but not to Lora.
 * DM Serif Display was tried during this shell workstream but was
 * never a licensing requirement (both fonts are SIL Open Font
 * License); the owner asked to keep the established Lora look
 * instead. A school logo, when shown, never appears anywhere near
 * this wordmark -- it lives in its own separate school-identity slot
 * elsewhere in the nav (see .raise-shell-school-identity below).
 *
 * Both .raise-shell-brand-word and .raise-shell-brand-badge carry an
 * explicit, unitless line-height (1) so their own geometry can never
 * be influenced by whatever line-height a given page (or, on the
 * seven tutor pages, a given SUBJECT's body style) happens to declare
 * -- a unitless value is recomputed from each element's own font-size
 * rather than inherited as a fixed length, which is what makes it
 * immune to a tutor page's body { line-height: 1.6 } vs another's
 * inherited `normal`. font-weight: 700 on both matches the public
 * site's .nav-brand/.nav-brand-badge exactly, so the wordmark reads as
 * the same typeface before and after signing in.
 *
 * On the mobile top bar, the mark sits in a small white capsule (the
 * originally accepted compact treatment, unchanged: 11px badge, 16px
 * "Learning"). On the desktop sidebar (>= 880px), it instead becomes a
 * full-width white masthead spanning the sidebar edge to edge, fixed
 * at exactly 54px tall (never content-driven -- see the
 * .raise-shell-nav .raise-shell-brand overrides in the 880px section
 * below) with the wordmark scaled up to match the public site's own
 * .nav-brand metrics precisely: 20px/700 "Learning", a 15px/700 badge
 * with 4px/10px padding and 6px radius. Its white background is a
 * fixed literal there too, so complete school branding recolours the
 * navigation surface immediately beneath the masthead without ever
 * touching the masthead or the wordmark itself.
 *
 * Adaptive foreground contrast: everything else in the sidebar/top
 * bar/tutor-topbar chrome (nav-link text and icons, the selected
 * nav-link pill, the collapse/close/menu buttons, dividers, focus
 * rings, the tutor top bar's subject label and Subject Hub button)
 * used to hardcode white text/icons on the assumption that
 * --raise-shell-accent/-secondary would always be dark enough for
 * that -- true for RAISE's own navy and most school colours, but not
 * a light one (e.g. a pale yellow), and not a genuinely mid-toned one
 * either (e.g. a mid grey), where neither navy nor white reaches WCAG
 * AA. public/branding.js now computes, alongside the accent colours
 * themselves, --raise-shell-on-accent-rgb and --raise-shell-on-accent-
 * secondary-rgb -- an "R, G, B" triplet that's RAISE's own navy or
 * white, whichever reaches >=4.5:1 contrast against that specific
 * accent colour (preferring the higher-contrast one if both pass), or
 * a guaranteed-dark black fallback for the narrow band where neither
 * does -- and every rule below reads var(--raise-shell-on-accent-rgb)
 * instead of a hardcoded 255, 255, 255 literal. Rules that colour
 * actual text or icon glyphs use the fully-opaque rgb(var(...)) form,
 * never rgba(var(...), alpha<1): alpha compositing blends a
 * translucent foreground toward the background underneath it, which
 * can pull an AA-passing colour back below 4.5:1 once rendered, so
 * text-bearing colour stays fully opaque and only non-text treatments
 * (hover backgrounds, borders, dividers) use a reduced alpha. General
 * and colour-agnostic: no school is special-cased, and RAISE's own
 * navy/pink defaults still resolve to exactly the same white
 * foregrounds this file always used, so nothing changes for the
 * default (unbranded) shell.
 *
 * The co-branding school logo, when shown, lives in its own slot,
 * .raise-shell-school-identity -- see the dedicated section below --
 * never beside the RAISE wordmark on either surface.
 *
 * .raise-shell-tutor-topbar is a second, desktop-only bar rendered by
 * app-shell.js into a placeholder that only the seven tutor pages
 * contain (in normal document flow at the top of their own .app
 * content column, not inside #raise-shell-root). It reads the exact
 * same --raise-shell-accent/-secondary variables as the sidebar, so
 * it recolours in lockstep with no separate JS wiring needed. It
 * carries no wordmark of its own -- that stays exclusively in the
 * desktop sidebar -- and is hidden entirely below the 880px desktop
 * breakpoint, where the mobile top bar (.raise-shell-topbar, already
 * carrying the wordmark + menu) is the only header shown.
 */

:root {
  --raise-shell-accent: #1B2340;
  --raise-shell-accent-secondary: #D6284A;
  --raise-shell-ink: #1B2340;
  --raise-shell-paper: #FAF6EE;
  --raise-shell-surface: #FFFFFF;
  --raise-shell-border: rgba(27, 35, 64, 0.14);
  --raise-shell-text: rgba(27, 35, 64, 0.78);
  --raise-shell-text-soft: rgba(27, 35, 64, 0.55);
  --raise-shell-radius: 10px;
  --raise-shell-topbar-height: 52px;
  --raise-shell-width-expanded: 220px;
  --raise-shell-width-collapsed: 60px;
  --raise-shell-width: var(--raise-shell-width-expanded);
  --raise-shell-font: 'Work Sans', 'DM Sans', system-ui, sans-serif;
  /* Adaptive foreground contrast -- public/branding.js computes and
     overwrites these on document.documentElement every time the
     accent colours change (RAISE default or a school's), choosing
     whichever of RAISE navy or white gives the higher WCAG contrast
     ratio against that specific colour. The literal defaults here
     match RAISE's own navy accent (a dark colour, correctly wanting
     white foregrounds), so navigation still renders correctly even
     before any branding.js call has run. */
  --raise-shell-on-accent-rgb: 255, 255, 255;
  --raise-shell-on-accent-secondary-rgb: 255, 255, 255;
}

@media (prefers-reduced-motion: reduce) {
  .raise-shell-nav,
  .raise-shell-scrim,
  .raise-shell-menu-btn i {
    transition: none !important;
  }
}

#raise-shell-root, .raise-shell, .raise-shell * {
  box-sizing: border-box;
}

/* ---------- Mobile-first: compact top app bar ----------
   Recolours with school branding, same as the sidebar -- defaults to
   RAISE's own navy. */
.raise-shell-topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--raise-shell-topbar-height);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  background: var(--raise-shell-accent);
  z-index: 1200; /* above raise-shell-nav's mobile drawer (1100) so the menu button is always reachable */
}

.raise-shell-menu-btn {
  appearance: none;
  border: none;
  background: transparent;
  /* Fully opaque, not rgba(..., alpha<1) -- this is icon-glyph
     "text", and alpha compositing would dilute the AA-checked colour
     against the actual accent background. */
  color: rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
  font-size: 20px;
  line-height: 1;
  padding: 8px;
  border-radius: var(--raise-shell-radius);
  cursor: pointer;
}
.raise-shell-menu-btn:hover { background: rgba(var(--raise-shell-on-accent-rgb, 255, 255, 255), 0.12); }
/* .raise-shell-menu-btn/-nav-close/-collapse-btn/-nav-link all sit
   directly on the --raise-shell-accent surface (the topbar/sidebar
   background itself), so their focus ring uses the SAME adaptive
   foreground already computed for that surface -- guaranteed visible
   against it by construction, whatever the current accent colour is.
   .raise-shell-brand and .raise-shell-back-link instead sit on a
   white/near-white surface (the wordmark's own fixed white panel, or
   the page's own light background) regardless of branding state, so
   they keep a fixed navy ring rather than reading a token meant for a
   different surface. */
.raise-shell-menu-btn:focus-visible,
.raise-shell-nav-close:focus-visible,
.raise-shell-collapse-btn:focus-visible,
.raise-shell-nav-link:focus-visible {
  outline: 2px solid rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
  outline-offset: 2px;
}
.raise-shell-brand:focus-visible,
.raise-shell-back-link:focus-visible {
  outline: 2px solid #1B2340;
  outline-offset: 2px;
}

/* ---------- Brand (shared markup, used twice) ----------
   .raise-shell-brand-mark (the RAISE wordmark chip) is permanently
   visible and carries fixed, literal colours -- never
   --raise-shell-accent/-secondary -- so it stays legible regardless
   of what colour the surrounding sidebar/top bar is currently
   showing. The school logo is never part of this chip -- see
   .raise-shell-school-identity below for its own, separate slot. */
.raise-shell-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.raise-shell-brand-mark {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: #FFFFFF;
  border-radius: 4px;
  padding: 5px 10px 5px 5px;
  flex-shrink: 0;
}
.raise-shell-brand-word {
  font-family: var(--font-display, 'Lora', Georgia, serif);
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
  color: #1B2340;
  white-space: nowrap;
}
.raise-shell-brand-badge {
  background: #1B2340;
  color: var(--color-marker-on-dark, #E4738A);
  font-family: var(--font-display, 'Lora', Georgia, serif);
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  padding: 3px 7px;
  border-radius: 2px;
}
.raise-shell-topbar-brand { flex: 1; min-width: 0; }

/* ---------- School identity (the co-branding logo's own slot) ----------
   A single, restrained area for the school's logo -- never beside the
   RAISE wordmark. Sits between the nav links and the collapse button
   in the DOM (see app-shell.js's buildSchoolIdentityHTML), so
   .raise-shell-nav-links' own flex: 1 naturally pushes it down to sit
   just above the collapse control on desktop -- "near the bottom-left
   of the expanded sidebar" -- with no extra positioning needed. The
   same markup, unmodified, also serves the mobile drawer (the same
   <nav> element, just off-canvas instead of persistent there): the
   collapse button is display: none on mobile, so this slot ends up
   sitting unobtrusively beneath the navigation links instead, exactly
   as required, with zero separate mobile-specific wiring.

   The logo box now has BOTH dimensions fixed (width and height, not
   just one with the other left to auto) with object-fit: contain --
   the standard "letterbox to fit, never stretch or crop" sizing for a
   replaced element inside a box whose aspect ratio may not match the
   image's own, so a square, landscape (wide) or portrait (tall) logo
   all size down to fit inside the box correctly, centred, with empty
   space on whichever axis the image is proportionally narrower than
   the box -- and can never overflow the sidebar on EITHER axis, since
   the box itself is a hard-fixed size regardless of the image's own
   natural dimensions. Its own white background + padding is the
   "neutral backing" needed for a transparent-background logo to stay
   legible against the currently-active accent colour, whatever that
   is.

   Two sizes, mobile-first like the rest of this file: this base rule
   is the mobile-drawer size (120px wide, 84px tall); the
   (min-width: 880px) block below overrides it to the larger
   144px-wide, 100px-tall expanded-desktop-sidebar size. Both figures
   are the settled midpoint between the original 72px/60px-tall
   height-driven sizes and the later 180x125/150x104 fixed-box sizes
   that read as too dominant once reviewed -- landing between "too
   small" and "too big" rather than re-opening either extreme. Both
   widths remain comfortably inside their container's real content
   width after every ancestor's own padding is subtracted (a looser
   margin than the previous, larger sizes needed, so neither is a
   close-run ceiling any more):
     desktop: 220px sidebar (--raise-shell-width-expanded) minus
       .raise-shell-nav's 12px+12px padding minus
       .raise-shell-school-identity's 6px+6px padding = 184px content
       width available -- 144px leaves a 40px margin.
     mobile: the narrowest drawer width in practice (min(82vw, 300px)
       bottoms out well above 220px on any realistically supported
       phone width) minus the same two paddings clears 120px with
       plenty of room to spare.
   .raise-shell-school-logo is border-box (the `.raise-shell *` rule
   up top), so a fixed width already caps its own padding too -- and
   with a fixed width AND height, object-fit: contain still guarantees
   an unusually wide, tall or square logo all stay fully visible and
   undistorted inside that exact box, never pressing past either
   edge, at either size. */
.raise-shell-school-identity {
  padding: 6px 6px 2px;
}
.raise-shell-school-logo {
  display: block;
  width: 120px;
  height: 84px;
  object-fit: contain;
  background: #FFFFFF;
  border-radius: 8px;
  /* Unchanged from the approved halved padding -- only the box
     dimensions above changed in this pass. */
  padding: 4px 6px;
}
/* [hidden] alone loses to a same-specificity display rule elsewhere in
   this file -- this explicit override makes sure branding.js's hidden
   toggling of the co-branding logo actually takes visual effect, so
   an unconfigured or failed logo disappears cleanly (its parent
   .raise-shell-school-identity has no background/border of its own,
   so nothing else is left visible once the image itself is hidden). */
.raise-shell-school-logo[hidden] {
  display: none;
}

/* ---------- Desktop tutor top bar (seven tutor pages only) ----------
   Hidden entirely below the desktop breakpoint -- see the 880px
   section below for the visible, in-flow desktop styling. */
.raise-shell-tutor-topbar {
  display: none;
}

/* ---------- Scrim (mobile drawer backdrop) ---------- */
.raise-shell-scrim {
  position: fixed;
  inset: 0;
  background: rgba(27, 35, 64, 0.4);
  z-index: 1050;
  opacity: 0;
  transition: opacity 0.18s ease;
}
.raise-shell-scrim[hidden] { display: none; }
.raise-shell-nav--open ~ .raise-shell-scrim,
.raise-shell-scrim:not([hidden]) { opacity: 1; }

/* ---------- Nav: off-canvas drawer by default (mobile/tablet) ----------
   Recolours with school branding -- defaults to RAISE's own navy, same
   token the mobile top bar reads, so both always match. */
.raise-shell-nav {
  position: fixed;
  top: 0; bottom: 0; left: 0;
  width: min(82vw, 300px);
  background: var(--raise-shell-accent);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 12px 16px;
  overflow-y: auto;
  z-index: 1100;
  transform: translateX(-100%);
  transition: transform 0.2s ease;
  /* Never covers/traps the page while closed -- fully off-canvas and inert. */
  visibility: hidden;
  pointer-events: none;
}
.raise-shell-nav--open {
  transform: translateX(0);
  visibility: visible;
  pointer-events: auto;
}
.raise-shell-nav-close {
  align-self: flex-end;
  appearance: none;
  border: none;
  background: transparent;
  /* Fully opaque -- see .raise-shell-menu-btn above. */
  color: rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
  font-size: 18px;
  padding: 6px;
  border-radius: var(--raise-shell-radius);
  cursor: pointer;
  margin-bottom: 4px;
}
.raise-shell-nav-close:hover { background: rgba(var(--raise-shell-on-accent-rgb, 255, 255, 255), 0.12); }
.raise-shell-nav .raise-shell-brand { padding: 4px 6px 14px; }

.raise-shell-nav-links {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.raise-shell-nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--raise-shell-radius);
  /* Fully opaque, not rgba(..., alpha<1) -- this IS the nav link's
     text, and its icon (.raise-shell-nav-link i, via inheritance);
     alpha compositing would dilute the AA-checked colour once
     rendered over the actual accent background. */
  color: rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
  text-decoration: none;
  font-family: var(--raise-shell-font);
  font-size: 13.5px;
  font-weight: 500;
}
.raise-shell-nav-link i { font-size: 16px; width: 18px; text-align: center; flex-shrink: 0; }
.raise-shell-nav-link:hover { background: rgba(var(--raise-shell-on-accent-rgb, 255, 255, 255), 0.08); }
.raise-shell-nav-link[aria-current="page"] {
  background: var(--raise-shell-accent-secondary);
  color: rgb(var(--raise-shell-on-accent-secondary-rgb, 255, 255, 255));
  font-weight: 600;
}
.raise-shell-nav-link--hub { margin-bottom: 6px; border-bottom: 1px solid rgba(var(--raise-shell-on-accent-rgb, 255, 255, 255), 0.16); border-radius: var(--raise-shell-radius) var(--raise-shell-radius) 0 0; padding-bottom: 12px; }

.raise-shell-collapse-btn {
  appearance: none;
  border: 1px solid rgba(var(--raise-shell-on-accent-rgb, 255, 255, 255), 0.28);
  background: transparent;
  /* Fully opaque -- see .raise-shell-menu-btn above. */
  color: rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
  border-radius: var(--raise-shell-radius);
  padding: 7px;
  cursor: pointer;
  align-self: flex-start;
  display: none; /* desktop-only control, see the 880px breakpoint below */
}

/* ---------- Tutor pages' own "Back to subject hub" action ----------
   Visually strengthens the existing link (a proper bordered pill,
   not bare text) without moving it or touching the header block
   around it -- the shared sidebar's own Subject Hub link and this
   page-local action coexist, serving different roles. Uses the same
   --raise-shell-accent token as the sidebar so it themes consistently
   under school branding. */
.raise-shell-back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--raise-shell-border);
  border-radius: var(--raise-shell-radius);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--raise-shell-accent, #1B2340);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.raise-shell-back-link:hover {
  background: rgba(27, 35, 64, 0.05);
  border-color: var(--raise-shell-accent, #1B2340);
}

/* ---------- Layout offsets on the rest of the page ---------- */
body { padding-top: var(--raise-shell-topbar-height); }

/* ---------- Desktop: persistent sidebar, no top bar, no drawer chrome ---------- */
@media (min-width: 880px) {
  body { padding-top: 0; padding-left: var(--raise-shell-width); }
  .raise-shell-topbar { display: none; }
  .raise-shell-scrim { display: none; }
  .raise-shell-nav {
    transform: none;
    visibility: visible;
    pointer-events: auto;
    width: var(--raise-shell-width);
    transition: width 0.15s ease;
  }
  .raise-shell-nav-close { display: none; }
  .raise-shell-collapse-btn { display: inline-flex; align-items: center; justify-content: center; margin-top: auto; }
  .raise-shell-nav--collapsed { width: var(--raise-shell-width-collapsed); }
  .raise-shell-nav--collapsed .raise-shell-brand-word,
  .raise-shell-nav--collapsed .raise-shell-nav-link span {
    display: none;
  }
  .raise-shell-nav--collapsed .raise-shell-nav-link { justify-content: center; }
  .raise-shell-nav--collapsed .raise-shell-collapse-btn i { transform: rotate(180deg); }

  /* Desktop sidebar masthead -- a full-width white bar spanning the
     sidebar edge to edge, replacing the compact floating pill used on
     mobile. Bleeds past .raise-shell-nav's own 14px/12px padding via
     negative margins (a stretched flex item's used width absorbs
     negative margins under align-items: stretch, so this reaches the
     nav's true edges with no extra width/calc() needed) -- no navy
     margin remains around it, and no rounded outer container. Its
     background is a fixed #FFFFFF literal, never --raise-shell-accent,
     so the navy/school-coloured navigation surface begins immediately
     below it, recolouring on its own without ever touching the
     masthead or the wordmark it contains.

     Height is a fixed 54px with box-sizing: border-box and horizontal-
     only padding -- deliberately NOT vertical padding driving the
     height, which is what previously let it vary page to page (the
     seven tutor pages each declare a different body line-height --
     e.g. Maths uses 1.6, Science inherits `normal` -- and that
     inherited value was reaching the wordmark's own line box). The
     fixed height plus .raise-shell-brand's own flex
     align-items: center (set once, unconditionally, above) vertically
     centres the wordmark regardless of content height, and the
     explicit unitless line-height on .raise-shell-brand-word/-badge
     (set once, unconditionally, above) means their own line-box height
     can no longer be influenced by an ancestor's line-height either --
     belt and braces, so every tutor's masthead measures identically. */
  .raise-shell-nav .raise-shell-brand {
    margin: -14px -12px 0;
    height: 54px;
    padding: 0 16px;
    box-sizing: border-box;
    background: #FFFFFF;
    border-bottom: 1px solid rgba(27, 35, 64, 0.08);
    justify-content: flex-start;
  }
  .raise-shell-nav .raise-shell-brand-mark {
    background: transparent;
    border-radius: 0;
    padding: 0;
    gap: 10px;
  }
  .raise-shell-nav .raise-shell-brand-badge {
    font-size: 15px;
    padding: 4px 10px;
    border-radius: 6px;
  }
  .raise-shell-nav .raise-shell-brand-word {
    font-size: 20px;
  }

  /* Expanded desktop sidebar: a larger co-branding logo box than the
     mobile-drawer default set above (144x100 vs 120x84) -- comfortably
     inside the real, padding-accounted-for content width of the 220px
     sidebar (see the comment above .raise-shell-school-logo's base
     rule for the exact arithmetic). */
  .raise-shell-school-logo {
    width: 144px;
    height: 100px;
  }

  /* Collapsed sidebar: the masthead narrows to just the badge, centred
     with reduced padding, so the masthead can never overflow the
     column regardless of branding state. Height stays the same fixed
     54px as the expanded masthead -- only the horizontal padding
     shrinks. The school-identity slot (up to 180px wide at this
     desktop size -- see above) is hidden entirely when collapsed,
     exactly like nav-link labels already hide there, for the same
     reason: it is far wider than the 60px collapsed column. */
  .raise-shell-nav--collapsed .raise-shell-brand {
    height: 54px;
    padding: 0 4px;
    box-sizing: border-box;
    justify-content: center;
  }
  .raise-shell-nav--collapsed .raise-shell-brand-badge {
    font-size: 10px;
    padding: 3px 6px;
  }
  .raise-shell-nav--collapsed .raise-shell-school-identity {
    display: none;
  }

  /* Desktop tutor top bar -- normal document flow at the top of the
     tutor page's own .app content column, never fixed/sticky, so it
     can never obscure the safeguarding bar or AI-accuracy notice that
     follow it -- it simply adds height above them like any other
     block. Reads the same accent variables as the sidebar directly,
     so it recolours identically under school branding with no extra
     JS wiring. */
  .raise-shell-tutor-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--raise-shell-accent);
    padding: 12px 18px;
    border-radius: var(--raise-shell-radius);
    margin-bottom: 1.5rem;
  }
  .raise-shell-tutor-topbar-subject {
    font-family: var(--raise-shell-font);
    font-weight: 600;
    font-size: 15px;
    color: rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
  }
  .raise-shell-tutor-topbar-hub {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--raise-shell-accent-secondary);
    color: rgb(var(--raise-shell-on-accent-secondary-rgb, 255, 255, 255));
    text-decoration: none;
    font-family: var(--raise-shell-font);
    font-weight: 600;
    font-size: 13px;
    padding: 7px 14px;
    border-radius: var(--raise-shell-radius);
    flex-shrink: 0;
    transition: opacity 0.15s;
  }
  .raise-shell-tutor-topbar-hub:hover { opacity: 0.88; }
  .raise-shell-tutor-topbar-hub:focus-visible {
    /* Sits against the tutor top bar's own --raise-shell-accent
       background (via outline-offset), not the hub button's own
       accent-secondary fill -- so this reads the accent (not
       accent-secondary) foreground token, same reasoning as the
       shared sidebar-chrome focus rule above. */
    outline: 2px solid rgb(var(--raise-shell-on-accent-rgb, 255, 255, 255));
    outline-offset: 2px;
  }
}
