/* ============================================================================
   YEAR 4 FRONT PAGE — scoped design system
   ============================================================================
   This file is loaded ONLY on the Year 4 overview page (home.html), which
   sets <body class="fy">. Every rule below is either:

     (a) a new component, namespaced "fy-" so it cannot collide with any
         class already defined in styles.css (which is loaded globally on
         every page, this one included), or

     (b) a scoped override of a handful of *real, functional* elements that
         app_base.html renders on every signed-in page (the topbar: its
         logo, title, sign-out button) — overridden here so they match this
         page's look, but the override only ever applies when body.fy is
         present, so no other page is affected.

   Nothing here is global. Deleting <link year4.css> and the "fy" body class
   returns home.html to the shared ledger design with zero residue.
   ============================================================================ */

body.fy {
  /* ---- Surfaces ---- */
  --fy-canvas: #FBF8F5;
  --fy-surface: #FFFFFF;
  --fy-border: #EFE6DD;
  --fy-border-strong: #E3D5C7;

  /* ---- Text ---- */
  --fy-ink: #1F1714;
  --fy-ink-2: #5E534C;
  --fy-ink-3: #9C9088;

  /* ---- Brand ---- */
  --fy-brand: #C2410C;
  --fy-brand-700: #9A3412;
  --fy-brand-600: #A5380B;
  --fy-brand-300: #F4B48C;
  --fy-brand-100: #FBE1CE;
  --fy-brand-50: #FFF3EA;

  --fy-gradient-brand: linear-gradient(120deg, #2A130A 0%, #5E2510 38%, #B44717 78%, #D9622A 100%);
  --fy-gradient-mark: linear-gradient(145deg, #DC5A1E, #9A3412);
  --fy-gradient-media: radial-gradient(120% 90% at 78% 30%, #FFFFFF 0%, rgba(255,255,255,0) 55%), linear-gradient(160deg, #FFF6EF 0%, #FDE8D8 100%);
  --fy-pattern-dots: radial-gradient(rgba(194, 65, 12, .13) 1px, transparent 1.3px);

  /* ---- Type ---- */
  --fy-font-display: "Source Serif 4", "Iowan Old Style", Georgia, serif;
  --fy-font-ui: "Geist", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* ---- Shape ---- */
  --fy-radius-xl: 24px;
  --fy-radius-lg: 20px;
  --fy-radius-md: 14px;
  --fy-radius-pill: 999px;

  /* ---- Elevation ---- */
  --fy-shadow-sm: 0 1px 2px rgba(50, 30, 15, .05);
  --fy-shadow-md: 0 1px 2px rgba(50, 30, 15, .04), 0 12px 30px -16px rgba(90, 45, 15, .18);
  --fy-shadow-lift: 0 2px 4px rgba(50, 30, 15, .05), 0 24px 44px -20px rgba(150, 60, 15, .35);

  /* ---- Motion ---- */
  --fy-ease: cubic-bezier(.2, .7, .2, 1);
  --fy-dur: .25s;

  background: var(--fy-canvas);
}

body.fy * { box-sizing: border-box; }
body.fy svg { display: block; flex: none; }
body.fy :focus-visible { outline: 2.5px solid var(--fy-brand); outline-offset: 3px; }

.fy-wrap { max-width: 1200px; margin: 0 auto; padding: 0 28px; }

/* ---------- Shared bits ---------- */
.fy-pill {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px; padding: 0 13px 0 10px;
  border-radius: var(--fy-radius-pill);
  background: var(--fy-brand-50); border: 1px solid var(--fy-brand-100);
  color: var(--fy-brand); font-size: 13px; font-weight: 600; white-space: nowrap;
  font-family: var(--fy-font-ui);
}
.fy-num-pill {
  min-width: 38px; height: 28px; padding: 0 10px;
  display: inline-grid; place-items: center;
  border-radius: var(--fy-radius-pill);
  background: rgba(255,255,255,.9); color: var(--fy-brand);
  border: 1px solid var(--fy-brand-100);
  font-family: var(--fy-font-display); font-style: italic; font-weight: 600; font-size: 15px;
  box-shadow: var(--fy-shadow-sm);
}
.fy-chip-glass {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px; padding: 0 14px 0 11px; border-radius: var(--fy-radius-pill);
  background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.24);
  color: #fff; font-size: 13px; font-weight: 500; white-space: nowrap;
  font-family: var(--fy-font-ui);
}

/* ---------- Shared topbar (real, functional element — scoped override) ---------- */
body.fy .topbar {
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--fy-border);
}
body.fy .topbar-in {
  max-width: 1200px; min-height: 72px; padding: 0 28px;
}
body.fy .logo {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--fy-gradient-mark);
  font-family: var(--fy-font-display); font-weight: 700; font-size: 20px;
  box-shadow: 0 6px 14px -6px rgba(194,65,12,.6), inset 0 1px 0 rgba(255,255,255,.25);
}
body.fy .topbar-title {
  font-family: var(--fy-font-ui); font-size: 17px; font-weight: 600;
  letter-spacing: -.01em; text-transform: none; color: var(--fy-ink);
}
body.fy .iconbtn {
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--fy-surface); color: var(--fy-ink-2);
  border: 1px solid var(--fy-border);
}
body.fy .iconbtn:hover {
  background: var(--fy-brand-50); color: var(--fy-brand); border-color: var(--fy-brand-100);
}
body.fy .content { max-width: none; padding: 0; }

/* ---------- Page header ---------- */
.fy-pagehead { position: relative; isolation: isolate; overflow-x: clip; }
.fy-pagehead::before {
  content: ""; position: absolute; z-index: -1; inset: 0 -28px;
  background-image: var(--fy-pattern-dots); background-size: 18px 18px;
  -webkit-mask-image: radial-gradient(70% 90% at 85% 40%, #000, transparent 75%);
          mask-image: radial-gradient(70% 90% at 85% 40%, #000, transparent 75%);
}
.fy-pagehead__inner {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 40px;
  padding-top: 56px; padding-bottom: 36px;
}
.fy-pagehead .fy-pill { margin-bottom: 20px; height: 34px; font-size: 13.5px; }
.fy-pagehead h1 {
  font-family: var(--fy-font-display); font-optical-sizing: auto;
  font-weight: 600; font-size: clamp(2.6rem, 5vw, 4rem);
  line-height: 1; letter-spacing: -.02em; color: var(--fy-ink); margin: 0;
}
.fy-pagehead__lede {
  margin-top: 16px; max-width: 44ch; font-size: 16.5px; line-height: 1.65;
  color: var(--fy-ink-2); font-family: var(--fy-font-ui);
}

.fy-stats {
  display: grid; grid-template-columns: repeat(3, auto);
  background: var(--fy-surface);
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-lg);
  box-shadow: var(--fy-shadow-md);
  overflow: hidden; flex: none; margin: 0;
}
.fy-stats > div { padding: 16px 24px 16px 20px; min-width: 116px; }
.fy-stats > div + div { border-left: 1px solid var(--fy-border); }
.fy-stats dt { font-size: 13px; font-weight: 500; color: var(--fy-ink-3); font-family: var(--fy-font-ui); margin: 0; }
.fy-stats dd { margin: 2px 0 0; font-family: var(--fy-font-display); font-weight: 600; font-size: 38px; line-height: 1.1; color: var(--fy-ink); }
.fy-stats .fy-is-brand { background: var(--fy-brand-50); }
.fy-stats .fy-is-brand dt, .fy-stats .fy-is-brand dd { color: var(--fy-brand); }

/* ---------- Blocks ---------- */
.fy-blocks { display: grid; gap: 48px; padding-top: 8px; padding-bottom: 96px; }

.fy-block-banner {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: center; gap: 20px;
  padding: 22px 26px;
  border-radius: var(--fy-radius-lg);
  background: var(--fy-gradient-brand); color: #fff;
  box-shadow: 0 16px 34px -22px rgba(120, 45, 10, .85);
}
.fy-block-banner::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(rgba(255,255,255,.12) 1px, transparent 1.3px);
  background-size: 16px 16px;
  -webkit-mask-image: linear-gradient(90deg, transparent 35%, #000);
          mask-image: linear-gradient(90deg, transparent 35%, #000);
}
.fy-block-banner__waves { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; }
.fy-block-banner__title { display: flex; align-items: baseline; gap: 12px; margin: 0; }
.fy-block-banner__label { font-size: 17px; font-weight: 500; color: rgba(255,236,224,.88); font-family: var(--fy-font-ui); }
.fy-block-banner__num { font-family: var(--fy-font-display); font-weight: 600; font-size: 52px; line-height: .95; letter-spacing: -.02em; }
.fy-block-banner__end { margin-left: auto; display: flex; align-items: center; gap: 16px; }

.fy-avatars { display: flex; }
.fy-avatars span {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: #FFF3EA; border: 2px solid rgba(255,255,255,.9);
  box-shadow: 0 4px 10px -4px rgba(0,0,0,.35);
}
.fy-avatars span + span { margin-left: -10px; }
.fy-avatars svg { width: 28px; height: 28px; }

.fy-modules {
  display: grid; gap: 24px; margin-top: 20px;
  grid-template-columns: repeat(var(--fy-cols, 3), minmax(0, 1fr));
}

/* ---------- Module card ----------
   Sized and weighted up from the first pass: taller media, roomier body,
   a larger corner radius, and a heavier rest-state shadow so each card
   reads as a substantial object on the page rather than a flat tile —
   same brand/ink/surface tokens throughout, nothing in the palette moved. */
.fy-module {
  position: relative; display: flex; flex-direction: column;
  background: var(--fy-surface);
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-xl);
  box-shadow: 0 1px 2px rgba(50,30,15,.06), 0 18px 38px -20px rgba(90,45,15,.28);
  overflow: hidden;
  font-family: var(--fy-font-ui);
  color: inherit; text-decoration: none;
  transition: transform var(--fy-dur) var(--fy-ease), box-shadow var(--fy-dur) var(--fy-ease), border-color var(--fy-dur) var(--fy-ease);
}
.fy-module__media {
  position: relative; height: 192px; margin: 10px 10px 0;
  border-radius: calc(var(--fy-radius-xl) - 6px);
  background: var(--fy-pattern-dots) 0 0 / 14px 14px, var(--fy-gradient-media);
  overflow: hidden;
}
.fy-module__media::before {
  content: ""; position: absolute; right: -30px; top: 50%;
  width: 198px; height: 198px; border-radius: 50%; transform: translateY(-50%);
  background: radial-gradient(circle at 40% 40%, #FFFFFF, #FCE3D0 70%);
  box-shadow: inset 0 0 0 1px rgba(194, 65, 12, .08);
}
.fy-module__art {
  position: absolute; right: 16px; top: 50%;
  width: 148px; height: 148px; transform: translateY(-50%);
  transition: transform .4s var(--fy-ease);
  filter: drop-shadow(0 10px 14px rgba(150, 60, 15, .16));
}
.fy-module__media .fy-num-pill { position: absolute; left: 14px; top: 14px; }

.fy-module__body { display: flex; flex-direction: column; flex: 1; padding: 22px 24px 24px; }
.fy-module__name {
  font-size: 19px; font-weight: 600; line-height: 1.32; letter-spacing: -.014em;
  text-wrap: balance; overflow-wrap: anywhere;
}
.fy-module__foot { margin-top: auto; padding-top: 22px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.fy-module__go {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center; flex: none;
  background: var(--fy-brand-50); color: var(--fy-brand);
  border: 1px solid var(--fy-brand-100);
  transition: background var(--fy-dur) var(--fy-ease), color var(--fy-dur) var(--fy-ease), transform var(--fy-dur) var(--fy-ease);
}

a.fy-module:hover {
  transform: translateY(-6px);
  box-shadow: 0 2px 4px rgba(50,30,15,.06), 0 30px 52px -22px rgba(150,60,15,.4);
  border-color: var(--fy-brand-100);
}
a.fy-module:hover .fy-module__art { transform: translateY(-50%) scale(1.07) rotate(-2deg); }
a.fy-module:hover .fy-module__go { background: var(--fy-brand); color: #fff; border-color: var(--fy-brand); transform: translateX(3px); }
a.fy-module:active { transform: translateY(-2px); }
a.fy-module:focus-visible { outline-offset: 4px; border-radius: var(--fy-radius-xl); }

/* Coming-soon cards are a <div>, not an <a> — no hover lift, no pointer,
   matches the rest of the app's "state carried by a word, not just colour
   or affordance" rule (see styles.css .status comment). */
div.fy-module { cursor: default; }
div.fy-module .fy-module__art { opacity: .82; }

@media (prefers-reduced-motion: reduce) {
  .fy-module, .fy-module__art, .fy-module__go { transition: none; }
  a.fy-module:hover { transform: none; }
  a.fy-module:hover .fy-module__art { transform: translateY(-50%); }
}

/* ---------- Responsive ---------- */
@media (max-width: 1080px) {
  .fy-modules[style*="--fy-cols:4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .fy-pagehead__inner { flex-direction: column; align-items: stretch; gap: 24px; padding-top: 40px; padding-bottom: 32px; }
  .fy-avatars { display: none; }
}
@media (max-width: 760px) {
  .fy-wrap { padding-left: 16px; padding-right: 16px; }
  body.fy .topbar-in { min-height: 62px; padding-left: 16px; padding-right: 16px; }
  body.fy .logo { width: 36px; height: 36px; font-size: 18px; }
  .fy-pagehead__lede { font-size: 15.5px; }
  .fy-blocks { gap: 36px; padding-bottom: 64px; }
  .fy-block-banner { padding: 16px 18px; border-radius: 18px; }
  .fy-block-banner__num { font-size: 40px; }
  .fy-modules, .fy-modules[style*="--fy-cols:4"] { grid-template-columns: 1fr; gap: 14px; margin-top: 14px; }
  .fy-module { flex-direction: row; align-items: stretch; }
  .fy-module__media { width: 130px; height: auto; min-height: 130px; margin: 7px 0 7px 7px; flex: none; }
  .fy-module__media::before { right: 50%; width: 132px; height: 132px; transform: translate(50%, -50%); }
  .fy-module__art { width: 96px; height: 96px; right: 50%; transform: translate(50%, -50%); }
  a.fy-module:hover .fy-module__art { transform: translate(50%, -50%) scale(1.05); }
  .fy-module__media .fy-num-pill { left: 6px; top: 6px; min-width: 32px; height: 24px; font-size: 13px; }
  .fy-module__body { padding: 16px 16px 16px 18px; }
  .fy-module__name { font-size: 16.5px; }
  .fy-module__foot { padding-top: 14px; }
  .fy-module__go { width: 32px; height: 32px; }
}

/* ============================================================================
   SEMANTIC COLOUR — extends the token set above for pages that need
   success/error/warning, not just brand. Same hues the ledger system used
   (so a screenshot from either era reads as "this app"), re-tuned warmer to
   sit next to --fy-canvas instead of --page.
   ============================================================================ */
body.fy {
  --fy-ok: #4D7C0F;
  --fy-ok-ink: #3F6A0C;
  --fy-ok-tint: #F3F7E8;

  --fy-wrong: #C0392B;
  --fy-wrong-ink: #9A2E22;
  --fy-wrong-tint: #FDEEEC;

  --fy-warn: #9A5B12;
  --fy-warn-ink: #7C480D;
  --fy-warn-tint: #FEF3E2;
}

/* ============================================================================
   TYPOGRAPHY PRIMITIVES — real classes from styles.css (.display, .h1, .h2,
   .lead, .cap/.eyebrow, .num), overridden so every page reads in the same
   voice as the front page: serif for headings, Geist for everything else.
   ============================================================================ */
body.fy .display {
  font-family: var(--fy-font-display);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.05;
  color: var(--fy-ink);
}
body.fy .h1 { font-size: clamp(1.9rem, 3.4vw, 2.6rem); }
body.fy .h2 { font-size: clamp(1.4rem, 2.2vw, 1.7rem); }
body.fy .lead {
  margin-top: 10px;
  font-family: var(--fy-font-ui);
  font-size: 16px;
  line-height: 1.6;
  color: var(--fy-ink-2);
  max-width: 60ch;
}
/* The kicker-above-heading pattern is deliberately not used on any page
   introduced here (topics, quiz, sign-in) — only the front page carries it,
   because that markup was pinned verbatim by the supplied reference file.
   .cap/.eyebrow still needs *a* style wherever the old markup happens to
   render one, but nothing new should reach for it. */
body.fy .cap, body.fy .eyebrow {
  font-family: var(--fy-font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fy-brand);
}
body.fy .num { font-family: var(--fy-font-display); font-variant-numeric: tabular-nums; }

/* ============================================================================
   SHELL EXTRAS — .content padding restored (home.html zeroes it and does its
   own via .fy-wrap; every other fy page keeps using .content normally).
   ============================================================================ */
body.fy .content {
  max-width: 1200px;
  padding: 40px 28px 96px;
}
@media (max-width: 760px) {
  body.fy .content { padding: 28px 16px 64px; }
}
/* home.html carries its own .fy-wrap per-section instead (its sections need
   different max-widths at different points), so it opts out here. */
body.fy-home .content { max-width: none; padding: 0; }

/* ============================================================================
   PAGE HEADER (topics / quiz pages) — real .pagehead/.facts classes,
   restyled to the soft/rounded fy language instead of the ledger's
   hard-ruled one. No eyebrow above the h1 here (see typography note above).
   ============================================================================ */
body.fy .pagehead {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  padding-bottom: 24px; margin-bottom: 32px;
  border-bottom: 1px solid var(--fy-border);
}
body.fy .pagehead-text { min-width: 0; flex: 1 1 320px; }
body.fy .pagehead .cap { display: block; margin-bottom: 6px; }

body.fy .facts {
  display: flex; flex: none;
  background: var(--fy-surface);
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-lg);
  box-shadow: var(--fy-shadow-sm);
  overflow: hidden;
}
body.fy .fact { padding: 12px 20px; min-width: 84px; }
body.fy .fact + .fact { border-left: 1px solid var(--fy-border); }
body.fy .fact dt { font-family: var(--fy-font-ui); font-size: 12.5px; font-weight: 500; color: var(--fy-ink-3); }
body.fy .fact dd { margin-top: 2px; font-size: 26px; font-weight: 600; color: var(--fy-ink); }

/* ============================================================================
   BUTTONS, LINKS, BACK, EMPTY, FIELD, ERROR, NOTE, TOAST — the shared
   vocabulary used on every fy page (topics search, quiz footer, sign-in,
   404). One button shape, one field shape, everywhere.
   ============================================================================ */
body.fy .btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 0 22px;
  background: var(--fy-brand); color: #fff;
  border: 1px solid var(--fy-brand);
  border-radius: var(--fy-radius-pill);
  font-family: var(--fy-font-ui); font-size: 15px; font-weight: 600;
  box-shadow: 0 10px 20px -12px rgba(194,65,12,.55);
  transition: background var(--fy-dur) var(--fy-ease), box-shadow var(--fy-dur) var(--fy-ease), transform var(--fy-dur) var(--fy-ease);
}
body.fy .btn:hover:not(:disabled) { background: var(--fy-brand-700); box-shadow: 0 14px 26px -12px rgba(194,65,12,.65); transform: translateY(-1px); }
body.fy .btn:active:not(:disabled) { transform: translateY(0); }
body.fy .btn:disabled { opacity: .55; cursor: default; box-shadow: none; }
body.fy .btn.secondary {
  background: var(--fy-surface); color: var(--fy-ink);
  border-color: var(--fy-border-strong); box-shadow: var(--fy-shadow-sm);
}
body.fy .btn.secondary:hover:not(:disabled) { background: var(--fy-brand-50); border-color: var(--fy-brand-100); color: var(--fy-brand-700); box-shadow: var(--fy-shadow-sm); transform: none; }

body.fy .link { color: var(--fy-brand); font-family: var(--fy-font-ui); font-size: 14px; text-decoration: underline; text-underline-offset: 3px; }
body.fy .link:hover { color: var(--fy-brand-700); }

body.fy .back {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px; margin-bottom: 20px;
  font-family: var(--fy-font-ui); font-size: 13.5px; font-weight: 600;
  color: var(--fy-ink-2); text-decoration: none;
}
body.fy .back:hover { color: var(--fy-brand); }

body.fy .empty {
  display: grid; justify-items: start; gap: 8px;
  padding: 56px 32px;
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-lg);
  background: var(--fy-surface);
  box-shadow: var(--fy-shadow-sm);
}
body.fy .empty .ic {
  display: grid; place-items: center;
  width: 52px; height: 52px; margin-bottom: 6px;
  border-radius: 50%;
  background: var(--fy-brand-50); color: var(--fy-brand);
}
body.fy .empty h3 { font-family: var(--fy-font-display); font-weight: 600; font-size: 22px; color: var(--fy-ink); }
body.fy .empty p { color: var(--fy-ink-2); max-width: 48ch; }

body.fy .field {
  display: block; width: 100%; min-height: 46px; padding: 0 16px;
  background: var(--fy-surface);
  border: 1px solid var(--fy-border-strong);
  border-radius: var(--fy-radius-md);
  font-family: var(--fy-font-ui); font-size: 15px; color: var(--fy-ink);
  transition: border-color var(--fy-dur) var(--fy-ease), box-shadow var(--fy-dur) var(--fy-ease);
}
body.fy .field:hover { border-color: var(--fy-ink-3); }
body.fy .field:focus { outline: none; border-color: var(--fy-brand); box-shadow: 0 0 0 3px var(--fy-brand-100); }

body.fy .err:not(:empty) {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 14px; padding: 12px 14px;
  background: var(--fy-wrong-tint); border: 1px solid var(--fy-wrong);
  border-radius: var(--fy-radius-md);
  color: var(--fy-wrong-ink); font-family: var(--fy-font-ui); font-size: 13.5px;
}

body.fy .note { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--fy-border); font-family: var(--fy-font-ui); font-size: 13px; line-height: 1.5; color: var(--fy-ink-3); }

body.fy .toast {
  background: var(--fy-ink); color: #fff;
  border-radius: var(--fy-radius-pill);
  box-shadow: var(--fy-shadow-lift);
  font-family: var(--fy-font-ui); font-size: 13.5px;
}

/* ============================================================================
   TOPICS — search bar, view toggle, and one topic row/card that switches
   layout via a single grid-template-areas swap keyed off [data-view] on the
   list container. The DOM never changes between modes, only the layout — so
   the existing client-side search filter (module_topics.html's inline
   script, which only toggles [hidden] on .topic) needs no changes at all.
   ============================================================================ */
body.fy .searchbar { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
body.fy .search-field { position: relative; flex: 1 1 240px; }
body.fy .search-field .icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--fy-ink-3); }
body.fy .search-field .field { padding-left: 40px; }
body.fy .qid-jump { display: flex; gap: 8px; flex: 1 1 340px; }
body.fy .qid-jump .field { flex: 1; min-width: 0; }
body.fy .empty-search { margin-top: 16px; color: var(--fy-ink-3); font-family: var(--fy-font-ui); font-size: 14px; }

.fy-viewtoggle {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--fy-surface); border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-pill); box-shadow: var(--fy-shadow-sm);
  margin-bottom: 20px;
}
.fy-viewtoggle-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 15px;
  border-radius: var(--fy-radius-pill);
  font-family: var(--fy-font-ui); font-size: 13.5px; font-weight: 600;
  color: var(--fy-ink-2);
  transition: background var(--fy-dur) var(--fy-ease), color var(--fy-dur) var(--fy-ease);
}
.fy-viewtoggle-btn .icon { color: currentColor; }
.fy-viewtoggle-btn:hover { color: var(--fy-ink); }
.fy-viewtoggle-btn.is-active { background: var(--fy-brand-50); color: var(--fy-brand); }

body.fy .topics {
  display: flex; flex-direction: column; gap: 10px;
}
body.fy .topics .topic + .topic { border-top: none; }

/* List mode (default): code, name(+badge), count, arrow are the four direct
   children of .topic-link in DOM order — that order already matches the
   desired left-to-right layout, so a plain 4-column grid needs no named
   areas at all. */
body.fy .topic-link {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center; gap: 14px;
  padding: 16px 18px;
  background: var(--fy-surface);
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-lg);
  box-shadow: var(--fy-shadow-sm);
  color: inherit; text-decoration: none;
  transition: transform var(--fy-dur) var(--fy-ease), box-shadow var(--fy-dur) var(--fy-ease), border-color var(--fy-dur) var(--fy-ease);
}
body.fy .topic-link:hover { transform: translateY(-2px); box-shadow: var(--fy-shadow-md); border-color: var(--fy-brand-100); }
body.fy .topic-link:hover .topic-name { color: var(--fy-brand-700); }
body.fy .topic-link .icon { color: var(--fy-ink-3); }

body.fy .topic-code {
  display: inline-grid; place-items: center;
  padding: 4px 9px;
  background: var(--fy-brand-50); color: var(--fy-brand);
  border-radius: var(--fy-radius-pill);
  font-family: var(--fy-font-display); font-style: italic; font-weight: 600; font-size: 12.5px;
  white-space: nowrap;
}
/* name + fallback badge travel together as one grid cell in list mode. */
body.fy .topic-name-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-width: 0; }
body.fy .topic-name { font-family: var(--fy-font-ui); font-size: 15.5px; font-weight: 600; line-height: 1.35; color: var(--fy-ink); }
body.fy .topic-fallback-badge {
  padding: 3px 9px;
  border: 1px solid var(--fy-warn); border-radius: var(--fy-radius-pill);
  background: var(--fy-warn-tint); color: var(--fy-warn-ink);
  font-family: var(--fy-font-ui); font-size: 11.5px; font-weight: 600;
  white-space: nowrap;
}
body.fy .topic-count {
  padding: 4px 10px; border-radius: var(--fy-radius-pill);
  background: var(--fy-canvas); border: 1px solid var(--fy-border);
  color: var(--fy-ink-2);
  font-family: var(--fy-font-ui); font-size: 12px; font-weight: 600;
  white-space: nowrap;
}

@media (max-width: 640px) {
  /* List mode only — card mode already reflows to one column via its own
     auto-fill grid and keeps its named areas. Grid gives way here to a
     simple wrapping flex row: code+name first line, count+arrow trail on
     their own line via order, no column math needed. */
  body.fy .topics:not([data-view="cards"]) .topic-link { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
  body.fy .topics:not([data-view="cards"]) .topic-code { order: 0; }
  body.fy .topics:not([data-view="cards"]) .topic-name-wrap { order: 1; flex: 1 1 100%; }
  body.fy .topics:not([data-view="cards"]) .topic-count { order: 2; }
  body.fy .topics:not([data-view="cards"]) .topic-link > .icon:last-child { order: 3; margin-left: auto; }
}

/* Card mode (default view): same four children, same DOM order — only the
   grid changes. Here the visual order genuinely differs from DOM order
   (count moves to the top-right, the arrow to the bottom-right), so this
   is the one case that needs named areas: .topic-name-wrap goes
   display:contents so its two possible children (name, and the fallback
   badge when present) can each take their own area instead of sharing one
   flex row.

   Sized and weighted to match the module cards on the QBanks page: same
   radius, same two-layer shadow formula, same hover lift, a circular
   filled "go" button instead of a bare arrow glyph. */
body.fy .topics[data-view="cards"] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: 22px;
}
body.fy .topics[data-view="cards"] .topic-link {
  grid-template-columns: 1fr auto;
  grid-template-areas: "code count" "name name" "meta go";
  row-gap: 12px;
  align-content: start;
  min-height: 184px;
  padding: 22px;
  border-radius: var(--fy-radius-xl);
  box-shadow: 0 1px 2px rgba(50,30,15,.06), 0 18px 38px -20px rgba(90,45,15,.28);
}
body.fy .topics[data-view="cards"] .topic-link:hover {
  transform: translateY(-5px);
  box-shadow: 0 2px 4px rgba(50,30,15,.06), 0 28px 48px -22px rgba(150,60,15,.38);
}
body.fy .topics[data-view="cards"] .topic-code {
  grid-area: code; justify-self: start;
  font-size: 13px; padding: 5px 11px;
}
body.fy .topics[data-view="cards"] .topic-count {
  grid-area: count; justify-self: end;
  font-size: 12.5px; padding: 5px 11px;
}
body.fy .topics[data-view="cards"] .topic-name-wrap { display: contents; }
body.fy .topics[data-view="cards"] .topic-name { grid-area: name; align-self: start; font-size: 17px; }
body.fy .topics[data-view="cards"] .topic-fallback-badge { grid-area: meta; justify-self: start; align-self: end; }
body.fy .topics[data-view="cards"] .topic-link > .icon:last-child {
  grid-area: go; justify-self: end; align-self: end;
  display: grid; place-items: center;
  width: 38px; height: 38px; padding: 0;
  border-radius: 50%;
  background: var(--fy-brand-50); border: 1px solid var(--fy-brand-100);
  color: var(--fy-brand);
  transition: background var(--fy-dur) var(--fy-ease), color var(--fy-dur) var(--fy-ease), transform var(--fy-dur) var(--fy-ease);
}
body.fy .topics[data-view="cards"] .topic-link:hover > .icon:last-child {
  background: var(--fy-brand); border-color: var(--fy-brand); color: #fff;
  transform: translateX(2px);
}

@media (max-width: 640px) {
  body.fy .topics[data-view="cards"] { grid-template-columns: 1fr; gap: 16px; }
}

/* ============================================================================
   QUIZ — question navigator, question card, options, and the reveal panel.
   Real classes driven by quiz.js (see that file); only presentation changes.
   ============================================================================ */
body.fy .fallback-banner {
  display: flex; align-items: flex-start; gap: 12px;
  margin-bottom: 24px; padding: 16px 18px;
  background: var(--fy-warn-tint); border: 1px solid var(--fy-warn);
  border-radius: var(--fy-radius-lg); color: var(--fy-warn-ink);
}
body.fy .fallback-banner p { font-family: var(--fy-font-ui); font-size: 13.5px; line-height: 1.55; }
body.fy .fallback-banner strong { font-family: var(--fy-font-ui); font-weight: 700; }

body.fy .qnav { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
body.fy .qnav-item {
  display: grid; place-items: center;
  min-width: 38px; height: 38px; padding: 0 6px;
  background: var(--fy-surface); border: 1px solid var(--fy-border-strong);
  border-radius: var(--fy-radius-pill);
  font-family: var(--fy-font-ui); font-size: 13px; font-weight: 700; color: var(--fy-ink-2);
  transition: background var(--fy-dur) var(--fy-ease), border-color var(--fy-dur) var(--fy-ease), transform var(--fy-dur) var(--fy-ease);
}
body.fy .qnav-item:hover { border-color: var(--fy-brand-300); transform: translateY(-1px); }
body.fy .qnav-item.is-current { background: var(--fy-brand); border-color: var(--fy-brand); color: #fff; }
body.fy .qnav-item.is-correct { background: var(--fy-ok-tint); border-color: var(--fy-ok); color: var(--fy-ok-ink); }
body.fy .qnav-item.is-wrong { background: var(--fy-wrong-tint); border-color: var(--fy-wrong); color: var(--fy-wrong-ink); }
body.fy .qnav-item.is-current.is-correct, body.fy .qnav-item.is-current.is-wrong { color: #fff; }

body.fy .qcard {
  padding: 28px 28px 26px;
  margin-bottom: 24px;
  background: var(--fy-surface);
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-xl);
  box-shadow: var(--fy-shadow-md);
}
body.fy .qid {
  margin-bottom: 12px;
  font-family: var(--fy-font-ui); font-size: 12.5px; font-weight: 700;
  letter-spacing: .04em; color: var(--fy-ink-3);
}
body.fy .qtext {
  margin-bottom: 26px;
  font-family: var(--fy-font-ui); font-size: 18px; font-weight: 500;
  line-height: 1.55; color: var(--fy-ink);
}

body.fy .opts { display: grid; gap: 12px; }
body.fy .opt {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 14px;
  width: 100%; padding: 14px 16px;
  background: var(--fy-surface);
  border: 1.5px solid var(--fy-border-strong);
  border-radius: var(--fy-radius-lg);
  text-align: left;
  transition: background var(--fy-dur) var(--fy-ease), border-color var(--fy-dur) var(--fy-ease), transform var(--fy-dur) var(--fy-ease);
}
body.fy .opt:hover:not(:disabled) { border-color: var(--fy-brand); background: var(--fy-brand-50); transform: translateY(-1px); }
body.fy .opt:disabled { cursor: default; }
body.fy .opt.pending { opacity: .55; }
body.fy .opt-letter {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--fy-canvas); border: 1.5px solid var(--fy-border-strong);
  font-family: var(--fy-font-ui); font-size: 13px; font-weight: 700; color: var(--fy-ink-2);
  transition: background var(--fy-dur) var(--fy-ease), border-color var(--fy-dur) var(--fy-ease), color var(--fy-dur) var(--fy-ease);
}
body.fy .opt-text { padding-top: 3px; font-family: var(--fy-font-ui); font-size: 15px; line-height: 1.5; color: var(--fy-ink); }
body.fy .opt-rationale { grid-column: 2; font-family: var(--fy-font-ui); font-size: 13.5px; line-height: 1.5; color: var(--fy-ink-3); }

body.fy .opt.correct { background: var(--fy-ok-tint); border-color: var(--fy-ok); }
body.fy .opt.correct .opt-letter { background: var(--fy-ok); border-color: var(--fy-ok); color: #fff; }
body.fy .opt.wrong { background: var(--fy-wrong-tint); border-color: var(--fy-wrong); }
body.fy .opt.wrong .opt-letter { background: var(--fy-wrong); border-color: var(--fy-wrong); color: #fff; }

body.fy .reveal {
  margin-top: 22px; padding: 18px 20px;
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-lg);
}
body.fy .reveal-correct { background: var(--fy-ok-tint); border-color: var(--fy-ok); }
body.fy .reveal-wrong { background: var(--fy-wrong-tint); border-color: var(--fy-wrong); }
body.fy .reveal-verdict {
  margin-bottom: 8px;
  font-family: var(--fy-font-ui); font-size: 13px; font-weight: 700; letter-spacing: .02em;
}
body.fy .reveal-correct .reveal-verdict { color: var(--fy-ok-ink); }
body.fy .reveal-wrong .reveal-verdict { color: var(--fy-wrong-ink); }
body.fy .reveal-explain { margin-bottom: 12px; font-family: var(--fy-font-ui); font-size: 15px; line-height: 1.6; color: var(--fy-ink); }
body.fy .reveal-keypoint { padding-top: 12px; border-top: 1px solid rgba(0,0,0,.08); font-family: var(--fy-font-ui); font-size: 13.5px; line-height: 1.5; color: var(--fy-ink-2); }

body.fy .qfooter { display: flex; gap: 12px; }
body.fy .qfooter .btn { flex: 1; }

/* ============================================================================
   SIGN IN — premium panel. No eyebrow above "Welcome back": the brand mark
   already says who this is; a text kicker on top of a heading is the exact
   pattern the rest of this system deliberately avoids introducing fresh.
   ============================================================================ */
body.fy .signin-wrap { background: var(--fy-canvas); }
body.fy .signin {
  padding: 40px;
  background: var(--fy-surface);
  border: 1px solid var(--fy-border);
  border-radius: var(--fy-radius-xl);
  box-shadow: var(--fy-shadow-lift);
  text-align: left;
}
body.fy .signin .logo {
  width: 48px; height: 48px; margin-bottom: 22px; border-radius: 50%;
  background: var(--fy-gradient-mark);
  font-family: var(--fy-font-display); font-weight: 700; font-size: 22px;
  box-shadow: 0 8px 18px -8px rgba(194,65,12,.6), inset 0 1px 0 rgba(255,255,255,.25);
}
body.fy .signin .eyebrow { display: none; }
body.fy .signin .h1 { font-size: 28px; }
body.fy .signin .lead { margin-bottom: 28px; font-size: 15px; }
body.fy .signin label {
  display: block; margin: 16px 0 8px;
  font-family: var(--fy-font-ui); font-size: 13px; font-weight: 600; color: var(--fy-ink-2);
}
body.fy .signin .btn { margin-top: 24px; }
body.fy .signin .link { display: inline-block; margin-top: 16px; }

/* ============================================================================
   SIDEBAR — persistent left nav on every signed-in page (app_base.html).
   Dark maroon rail (the same dark stops as --fy-gradient-brand, just read
   top-to-bottom and kept in their darkest range so the light nav text
   stays readable) against the light canvas everywhere else — the one
   deliberately Committed surface in an otherwise Restrained palette, same
   pattern Claude's own UI uses for its sidebar.

   Always position:fixed, at every breakpoint — not sticky — specifically
   so it spans the full viewport height regardless of how tall the content
   next to it gets; margin-left on .app-main (desktop) makes room for it
   instead of relying on normal flex flow. Collapses to an icon-only rail
   (html.sb-collapsed, desktop only) or slides in as a mobile drawer
   (.sidebar.is-open, <900px) — see app_base.html's inline script for both.

   .app-shell, not bare .app: login.html also carries body.fy and its own
   .app, and must keep its original centered column layout untouched.
   ============================================================================ */
body.fy {
  --fy-sidebar-w: 264px;
  --fy-sidebar-w-collapsed: 76px;
  --fy-sidebar-bg: linear-gradient(180deg, #2A130A 0%, #3B190D 55%, #431B0E 100%);
  --fy-sidebar-ink: rgba(255, 246, 239, .92);
  --fy-sidebar-ink-dim: rgba(255, 246, 239, .5);
  --fy-sidebar-hover: rgba(255, 255, 255, .07);
  --fy-sidebar-active-bg: rgba(217, 98, 42, .24);
  --fy-sidebar-active-ink: #FFD9BC;
}

body.fy .app-shell {
  flex-direction: row;
  align-items: stretch;
}

.sidebar-backdrop {
  position: fixed; inset: 0; z-index: 45;
  background: rgba(20, 12, 8, .5);
}

body.fy .sidebar {
  width: var(--fy-sidebar-w); flex: none;
  display: flex; flex-direction: column;
  background: var(--fy-sidebar-bg);
  padding: 20px 14px;
  position: fixed; left: 0; top: 0; z-index: 40;
  height: 100dvh; overflow-y: auto; overflow-x: hidden;
  box-shadow: 4px 0 24px -12px rgba(20, 10, 5, .3);
  transition: width var(--fy-dur) var(--fy-ease), transform var(--fy-dur) var(--fy-ease);
}

.sidebar-brand { display: flex; align-items: center; gap: 12px; padding: 0 8px; margin-bottom: 24px; min-height: 36px; }
.sidebar-brand .logo {
  width: 36px; height: 36px; flex: none; border-radius: 50%;
  background: var(--fy-gradient-mark);
  font-family: var(--fy-font-display); font-weight: 700; font-size: 17px;
  box-shadow: 0 6px 14px -6px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.25);
}
.sidebar-brand-name { flex: 1; min-width: 0; font-family: var(--fy-font-display); font-weight: 600; font-size: 18px; color: #fff; white-space: nowrap; }
.sidebar-collapse-toggle {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: var(--fy-radius-md);
  border: none; background: none; color: var(--fy-sidebar-ink-dim); cursor: pointer;
  transition: background var(--fy-dur) var(--fy-ease), color var(--fy-dur) var(--fy-ease);
}
.sidebar-collapse-toggle:hover { background: var(--fy-sidebar-hover); color: #fff; }

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.sidebar-bottom { display: flex; flex-direction: column; gap: 2px; padding-top: 14px; margin-top: 14px; border-top: 1px solid rgba(255,255,255,.09); }
.sidebar-signout-form { display: contents; }

.sidebar-link {
  display: flex; align-items: center; gap: 12px;
  width: 100%; height: 44px; padding: 0 12px;
  border: none; background: none; cursor: pointer; text-align: left;
  border-radius: var(--fy-radius-md);
  font-family: var(--fy-font-ui); font-size: 14.5px; font-weight: 500; color: var(--fy-sidebar-ink);
  text-decoration: none; white-space: nowrap;
  transition: background var(--fy-dur) var(--fy-ease), color var(--fy-dur) var(--fy-ease);
}
.sidebar-link .icon { flex: none; color: var(--fy-sidebar-ink-dim); transition: color var(--fy-dur) var(--fy-ease); }
.sidebar-link:hover { background: var(--fy-sidebar-hover); color: #fff; }
.sidebar-link:hover .icon { color: #fff; }
.sidebar-link.is-active { background: var(--fy-sidebar-active-bg); color: var(--fy-sidebar-active-ink); font-weight: 600; }
.sidebar-link.is-active .icon { color: var(--fy-sidebar-active-ink); }
.sidebar-signout:hover { background: rgba(224, 90, 70, .22); color: #FFD3CB; }
.sidebar-signout:hover .icon { color: #FFD3CB; }

.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar-mobile { display: none; }

@media (min-width: 900px) {
  .sidebar-backdrop, #sidebar-toggle { display: none; }

  body.fy .sidebar { transform: none; }
  .app-main { margin-left: var(--fy-sidebar-w); transition: margin-left var(--fy-dur) var(--fy-ease); }

  /* Collapsed rail: icon-only, centered, labels and the wordmark gone. */
  html.sb-collapsed body.fy .sidebar { width: var(--fy-sidebar-w-collapsed); }
  html.sb-collapsed .app-main { margin-left: var(--fy-sidebar-w-collapsed); }
  html.sb-collapsed .sidebar-brand { flex-direction: column; gap: 10px; padding: 0; }
  html.sb-collapsed .sidebar-brand-name { display: none; }
  html.sb-collapsed .sidebar-link { justify-content: center; padding: 0; }
  html.sb-collapsed .sidebar-link span { display: none; }
  html.sb-collapsed .sidebar-collapse-toggle .icon { transform: scaleX(-1); }
}

@media (max-width: 899px) {
  body.fy .sidebar {
    transform: translateX(-100%);
    box-shadow: var(--fy-shadow-lift);
  }
  body.fy .sidebar.is-open { transform: translateX(0); }
  .sidebar-collapse-toggle { display: none; }

  .topbar-mobile {
    display: flex; align-items: center; gap: 12px;
    height: 60px; padding: 0 16px;
    background: rgba(255,255,255,.92);
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--fy-border);
    position: sticky; top: 0; z-index: 20;
  }
  .topbar-mobile .logo {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--fy-gradient-mark);
    font-family: var(--fy-font-display); font-weight: 700; font-size: 15px;
  }
  .topbar-mobile .topbar-title { flex: 1; font-family: var(--fy-font-ui); font-weight: 600; font-size: 15px; color: var(--fy-ink); }

  body.sidebar-locked { overflow: hidden; }
}

/* ============================================================================
   YEAR PICKER ("/") + YEAR 5 SUBJECTS ("/year5")

   Both reuse the .fy-module card shell above, so palette, radius, shadows and
   the "link only when open" rule are shared with Year 4 - only the media
   panel's contents change (a numeral for a year, an icon disc for a subject).

   COLUMNS follow the space the *wrapper* has, not the viewport: the sidebar
   takes 264px (or 76px collapsed) off the desktop viewport, so a viewport
   breakpoint would pick the wrong column count half the time. The wrappers
   are the containers; the grids inside them respond. Browsers without
   container queries keep the base column count, which is a safe layout.
   The <=760px phone rules further down are viewport-based and come last, so
   they win over the container rules where the two overlap.
   ============================================================================ */
.fy-years-wrap, .fy-subjects-wrap { container-type: inline-size; padding-top: 8px; padding-bottom: 96px; }

/* ---------- Year picker ---------- */
.fy-years { display: grid; gap: 20px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
@container (min-width: 1040px) {
  .fy-years { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.fy-year .fy-module__media { height: 168px; }
.fy-year .fy-module__media::before {
  right: 50%; transform: translate(50%, -50%); width: 150px; height: 150px;
}
.fy-year__numeral {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -52%);
  font-family: var(--fy-font-display); font-style: italic; font-weight: 600;
  font-size: 92px; line-height: 1; color: var(--fy-brand);
  text-shadow: 0 10px 14px rgba(150, 60, 15, .16);
  transition: transform .4s var(--fy-ease);
}
.fy-year .fy-module__body { padding: 20px 20px 22px; }
a.fy-year:hover .fy-year__numeral { transform: translate(-50%, -52%) scale(1.06); }
div.fy-year .fy-year__numeral { opacity: .82; }

/* ---------- Year 5 subjects ----------
   Same card, one step more refined: a taller media panel, more air inside and
   between cards, a lighter name weight with tighter tracking, a softer resting
   shadow, and a gentler lift. Nothing in the palette moves. */
.fy-subjects { display: grid; gap: 28px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@container (min-width: 700px) {
  .fy-subjects { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@container (min-width: 1040px) {
  .fy-subjects { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

body.fy-y5 .fy-pagehead__inner { padding-top: 64px; padding-bottom: 44px; }
body.fy-y5 .fy-pagehead h1 { font-weight: 560; letter-spacing: -.024em; }
body.fy-y5 .fy-pagehead__lede { line-height: 1.7; }
.fy-subjects-wrap { padding-bottom: 104px; }

.fy-subject {
  box-shadow: 0 1px 2px rgba(50, 30, 15, .05), 0 22px 44px -26px rgba(90, 45, 15, .24);
}
.fy-subject .fy-module__media { height: 208px; margin: 12px 12px 0; }
.fy-subject .fy-module__body { padding: 26px 28px 28px; }
.fy-subject .fy-module__name { font-size: 20px; font-weight: 560; letter-spacing: -.018em; line-height: 1.3; }
.fy-subject .fy-module__foot { padding-top: 26px; }

/* The subject's icon sits on a white disc centred in the media panel's pale
   circle (the circle is 198px, right:-30px, so its centre is 69px from the
   panel's right edge; a 116px disc at right:11px lands exactly on it). */
.fy-subject__disc {
  position: absolute; right: 11px; top: 50%;
  width: 116px; height: 116px; border-radius: 50%;
  display: grid; place-items: center;
  background: #fff; color: var(--fy-brand);
  border: 1px solid var(--fy-brand-100);
  box-shadow: 0 1px 2px rgba(50, 30, 15, .05), 0 14px 26px -14px rgba(150, 60, 15, .4);
  transform: translateY(-50%);
  transition: transform .4s var(--fy-ease), box-shadow .4s var(--fy-ease);
}
.fy-subject__disc .icon { width: 52px; height: 52px; stroke-width: 1.4; }

/* Hover. Every card warms its border and nudges its disc - decorative, no
   lift, so a coming-soon card doesn't pretend to be clickable. Only a real
   link (<a>) also lifts. */
.fy-subject:hover { border-color: var(--fy-brand-100); }
.fy-subject:hover .fy-subject__disc {
  transform: translateY(-50%) scale(1.05);
  box-shadow: 0 1px 2px rgba(50, 30, 15, .05), 0 18px 30px -14px rgba(150, 60, 15, .48);
}
a.fy-subject:hover {
  transform: translateY(-5px);
  box-shadow: 0 2px 4px rgba(50, 30, 15, .05), 0 30px 54px -26px rgba(150, 60, 15, .34);
}
a.fy-subject:active { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  .fy-year__numeral, .fy-subject__disc { transition: none; }
  a.fy-year:hover .fy-year__numeral { transform: translate(-50%, -52%); }
  a.fy-subject:hover { transform: none; }
  .fy-subject:hover .fy-subject__disc { transform: translateY(-50%); }
}

/* ---------- Phones: same row-card layout as the Year 4 module cards ---------- */
@media (max-width: 760px) {
  .fy-years, .fy-subjects { grid-template-columns: 1fr; gap: 14px; }
  .fy-years-wrap, .fy-subjects-wrap { padding-top: 0; padding-bottom: 64px; }

  .fy-year .fy-module__media { height: auto; min-height: 120px; }
  .fy-year .fy-module__media::before { width: 96px; height: 96px; }
  .fy-year__numeral { font-size: 58px; }
  .fy-year .fy-module__body { padding: 16px 16px 16px 18px; }

  .fy-subject .fy-module__media { height: auto; min-height: 130px; margin: 7px 0 7px 7px; }
  .fy-subject .fy-module__body { padding: 16px 16px 16px 18px; }
  .fy-subject .fy-module__name { font-size: 17px; }
  .fy-subject .fy-module__foot { padding-top: 14px; }
  .fy-subject__disc { right: 50%; width: 84px; height: 84px; transform: translate(50%, -50%); }
  .fy-subject__disc .icon { width: 38px; height: 38px; }
  .fy-subject:hover .fy-subject__disc { transform: translate(50%, -50%) scale(1.05); }
  body.fy-y5 .fy-pagehead__inner { padding-top: 40px; padding-bottom: 32px; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 760px) {
  .fy-subject:hover .fy-subject__disc { transform: translate(50%, -50%); }
}
