/* FreeEdu (Free Education) — the shared layout stylesheet.
   A port of the prototype's one real stylesheet (design/prototype.html:21-88) plus the
   chrome classes lifted out of its inline styles.

   Why a shared sheet and not scoped .razor.css: everything here is a cross-component
   layout primitive — .fe-wrap sets the page measure on seven screens, .fe-reader is a
   grid whose two halves are different components, and the --ui-* variables are read by
   every element on the site. Per-component styles still belong in that component's
   .razor.css (reference doc §5).

   Everything below is token-only. No colour, radius, shadow, font or duration is written
   as a literal where the design system already names one (reference doc §13 rule 6).

   THE PAGE GROUND IS NOT SET HERE, and no longer needs to be. This file loads after
   ds/styles.css, whose base.css sets body's background to the PORTAL's --surface-page; that
   used to be left alone deliberately, because the portal shares this document and must keep
   its own ground. fe-ds.css now states FreeEdu's ground fenced behind the site marker —
   `[data-fe-site] body { background: var(--bg) }` — which overrides the portal's for FreeEdu
   pages only and leaves portal pages untouched.

   So the ground is stated once, in one file, and nothing in here may paint over it. See the
   note on .fe-app, which did, and what it cost in dark mode. */

/* -- Language-driven typography ------------------------------------------------------
   The mechanism that makes Urdu typography work, and the reason there is no per-context
   Urdu metric table anywhere in this codebase. Every element reads var(--ui-font) /
   var(--ui-line) / var(--ui-tight) / var(--ui-head), so re-stamping html[lang] reflows
   the entire site's typography in one step — no component branches on language.
   Nastaliq needs roughly 1.45x the leading of a Latin face at the same size; that ratio
   is what the three line-height variables encode. (reference doc §5) */

:root {
  /* Urdu is the default: html carries lang="ur" dir="rtl" unless a reader chose English. */
  --ui-font: var(--fe-font-urdu);
  --ui-line: 2.35;   /* body copy */
  --ui-tight: 2.0;   /* controls, labels, single-line text */
  --ui-head: 1.95;   /* headings */
  --ui-nudge: 0.06em;
  --fe-rs: 1;        /* reader zoom factor, driven by the A- / A+ control (F29) */
}

html[lang="en"] {
  --ui-font: var(--font-sans);
  --ui-line: 1.62;
  --ui-tight: 1.45;
  --ui-head: 1.18;
  --ui-nudge: 0;
}

/* A SHEET CAN DECLARE A LANGUAGE ITS PAGE DOES NOT, AND THE BLOCK ABOVE CANNOT SEE IT.
   --ui-* are custom properties: they resolve by INHERITANCE from <html>, so :lang() cannot
   reach them and a wrapper saying lang="ur" inside an English page still draws the Latin
   metrics. That is the whole of Mutala-e-Quran-e-Hakeem — the library's one Urdu-only
   subject, every chapter, every class, every KP board — reaching an English reader with its
   rail, its group headings, its search box and its answer labels set in the Latin UI face.

   ChapterPage and SubjectPage stamp lang on .fe-wrap with the language their CHROME is in
   (SheetLangCode), and this restates the Urdu block for that subtree. The sheet then reads
   exactly as it does on the Urdu site, while the site's own header and footer sit outside
   .fe-wrap and keep saying what the reader actually chose. */
.fe-wrap:lang(ur) {
  --ui-font: var(--fe-font-urdu);
  --ui-line: 2.35;
  --ui-tight: 2.0;
  --ui-head: 1.95;
  --ui-nudge: 0.06em;
}

/* -- Page measure -------------------------------------------------------------------- */

/* THE MEASURE IS THE DESIGN SYSTEM'S NOW. This was 1060px with a fixed 16px gutter —
   divergence D12, decided against an older handoff. The new design files set
   .wrap{max-width:var(--max);padding-inline:clamp(1.1rem,4vw,2.5rem)} with --max:1160px,
   and every section of every one of those pages sits in it.

   Two things were wrong, not one. The page was 100px narrower than the design, which is
   visible the moment a Home section sits beside a mock screenshot; and the 16px gutter was
   FIXED, so a phone got the same margin as a 1400px laptop where the design ramps from
   1.1rem to 2.5rem. Restated here rather than renaming every .fe-wrap in the project to
   .wrap: one wrapper class, now carrying the design system's values, corrects every page
   at once and leaves the two narrow variants below working as overrides. */
.fe-wrap {
  width: 100%;
  max-width: var(--max, 1160px);
  margin-inline: auto;
  padding-inline: clamp(1.1rem, 4vw, 2.5rem);
  box-sizing: border-box;
}

/* The three narrow screens (how-to, about, app) tighten the measure rather than the wrap. */
.fe-wrap-720 { max-width: 720px; }
.fe-wrap-680 { max-width: 680px; }

/* THE OLD BUTTON, EYEBROW, LEDE AND PAGE-TITLE RULES WERE HERE AND ARE GONE.

   .fe-btn / .fe-btn-primary / .fe-btn-ghost / .fe-btn-text / .fe-eyebrow / .fe-lede /
   .fe-pagetitle were the previous design's versions of components fe-ds.css now owns as
   .btn / .btn--ghost / .eyebrow / .lede / .page-head > h1. They drew from the ADMIN
   PORTAL's tokens (--brand-primary, --text-secondary, --radius-md), so every call to
   action on the FreeEdu site was still rendering in the portal's mint and the portal's
   radius while the page around it had moved to the landing design.

   All seven names are now absent from every .razor in the project. .fe-strip, .fe-steps3
   and .fe-qstrip went with them: they were layout primitives for screens that no longer
   use them.

   WHAT DELIBERATELY STAYS in this file: .fe-wrap, .fe-tap, .fe-nav, .fe-link, .fe-row,
   .fe-in, .fe-scroll, .fe-reader/.fe-rail and the --ui-* language variables. Those are
   not design decisions the mock has an opinion about — they are this app's tap-target
   floor, its RTL-aware scroll container, its reader grid, and the mechanism that swaps
   the whole site's typography when the language pill is clicked. */

/* -- Layout primitives --------------------------------------------------------------- */

/* .fe-cards and .fe-tiles WERE HERE AND ARE GONE. They were the Find flow's two grids;
   FindClass now uses the design system's .class-grid and FindBoard/FindSubject use its
   .subj-grid, so both names were dead in every .razor in the project. Their two
   responsive overrides below went with them. */

.fe-reader { display: grid; grid-template-columns: 1fr; gap: 18px; align-items: start; }

.fe-rail { order: 2; padding: 16px; }
.fe-full { display: block; }
.fe-mini { display: none; }

/* -- Rows and hover states ------------------------------------------------------------
   All hover transitions are the design system's single --transition-fast (.12s ease);
   the DS motion token is the authority, not the literal the prototype inlined. */

.fe-row { border-bottom: 1px solid var(--border); }
.fe-row:last-child { border-bottom: 0; }

.fe-row:hover  { background: rgba(46, 212, 165, .10); }
.fe-qrow:hover { background: rgba(46, 212, 165, .10); }
.fe-tap:hover  { border-color: var(--accent); background: rgba(46, 212, 165, .10); }
.fe-nav:hover  { background: var(--surface-2); color: var(--fg); }
.fe-link:hover { color: var(--accent); }

.fe-row, .fe-qrow, .fe-tap, .fe-nav, .fe-link { transition: var(--t); }

/* -- Responsive visibility pairs ------------------------------------------------------
   Each pair is mutually exclusive: exactly one of the two is displayed at any width.
   Base (mobile) values here; the 860px block below swaps every pair at once. */

/* .fe-navlist is gone with the old header — the bar's links are .nav-links now, and
   fe-ds.css hides THEM below 860px (the new design files' own breakpoint). This side of
   the pair is still fe.css's, because the burger row has no counterpart in those files. */
.fe-navmob  { display: flex; align-items: center; gap: 6px; }
.fe-toc     { display: none; }
.fe-tocmob  { display: block; }

/* -- Utilities ----------------------------------------------------------------------- */

/* The reader text-size control (F29). zoom — not font-size — because the whole card
   scales together: badges, rules, chips and equations keep their proportions. */
.fe-read { zoom: var(--fe-rs, 1); }

.fe-clamp2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Horizontal scroller with the bar hidden — the wizard's step-chip rail. Both vendor
   forms are needed: Firefox honours scrollbar-width, WebKit only the pseudo-element. */
.fe-scroll { overflow-x: auto; scrollbar-width: none; }
.fe-scroll::-webkit-scrollbar { display: none; }

/* The shared input. min-height 44px is the tap-target floor the prototype holds
   everywhere (reference doc §13 rule 9) — do not shrink it to fit a layout. */
.fe-in {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--ui-font);
  font-size: 14px;
  line-height: var(--ui-tight);
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 9px 12px;
  min-height: 44px;
}
.fe-in:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.fe-in::placeholder { color: var(--muted); }

/* -- Page furniture -------------------------------------------------------------------
   Added by Phase 4 (T4.1-T4.8). The prototype inlines a card, a button and a reading-size
   paragraph on the home page and on all three static pages, with the same values each time;
   these are the four screens' shared vocabulary, so they belong here rather than repeated in
   four scoped stylesheets. Anything used by exactly ONE screen stays in that screen's
   .razor.css — see the note at the top of Home.razor.css.

   None of them can be ported as the prototype writes them: InlineStyleGuardrailTests fails any
   style attribute in .razor markup that is not a bare custom-property assignment (L22). */

/* The card: background, border and radius only. Every use has its own padding — 18px 20px on
   a stat card, 17px 19px on a promise card, 20px on the teaser, and none at all on the About
   table, which pads its rows instead — so a card that also dictated padding would be
   overridden at every call site, which is not a default. */
.fe-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}

/* THE OLD BUTTON, EYEBROW AND PAGE-TITLE RULES WERE HERE AND ARE GONE.

   .fe-btn / .fe-btn-primary / .fe-btn-ghost / .fe-btn-text / .fe-eyebrow / .fe-lede /
   .fe-pagetitle were the previous design's versions of components fe-ds.css now owns as
   .btn / .btn--ghost / .eyebrow / .lede / .page-head > h1. They drew from the ADMIN
   PORTAL's tokens (--brand-primary-strong, --text-primary, --radius-md), so every call to
   action on the FreeEdu site still rendered in the portal's mint and the portal's radius
   while the page around it had moved to the landing design. All seven names are now absent
   from every .razor in the project.

   Two corrections they used to carry are NOT lost, because the design system makes them
   itself. The first is L58's: ds/tokens/base.css tracks every <h1> at -0.02em, which is
   Latin display tracking landing on Nastaliq, a joined script whose letterforms are drawn
   to meet; .fe-pagetitle restated letter-spacing:normal to undo it, and fe-ds.css instead
   sets its own tracking on headings and zeroes it again under html[lang="ur"]. The second
   is the eyebrow's: portal.css's .eyebrow is permanently uppercase, which is meaningless
   in Urdu; fe-ds.css's .eyebrow is not uppercase at all, and only .mono and .kicker
   uppercase — each of which drops text-transform under html[lang="ur"].

   WHAT DELIBERATELY STAYS in this file: .fe-wrap, .fe-card, .fe-tap, .fe-nav, .fe-link,
   .fe-row, .fe-in, .fe-scroll, .fe-reader/.fe-rail and the --ui-* language variables.
   Those are not decisions the mock has an opinion about — they are this app's tap-target
   floor, its RTL-aware scroll container, its reader grid, and the mechanism that swaps the
   whole site's typography when the language pill is clicked. */

/* -- Chrome ---------------------------------------------------------------------------
   Lifted out of the prototype's inline styles (lines 121-158, 718-736), which cannot be
   ported as-is: InlineStyleGuardrailTests fails any style="..." in .razor markup that is
   not a bare custom-property assignment. Phase 3 (F1-F3) refines these; the geometry
   below is already the prototype's. */

/* NO BACKGROUND HERE. This element is 100vh and wraps the header, the page and the footer,
   so anything it paints IS the page ground and body's is never seen. It used to paint
   var(--surface-2), which was right when the file header above was written — the ground was
   the portal's --surface-page and the prototype asked for --surface-2 — and became wrong the
   moment fe-ds.css declared `[data-fe-site] body { background: var(--bg) }`. Since then the
   design system named one page ground and this rule covered it up.

   IT HID ALMOST ENTIRELY IN LIGHT MODE, which is why it survived: --surface-2 is #EEF1F5 and
   --bg is #F7F8FA, four units apart. In dark they are #182036 and #0B0F1E, and the difference
   is the whole bug:

     - the page read as washed-out slate instead of the design's near-black navy;
     - .stats paints var(--surface-2), so the counters band was the SAME colour as the page
       and disappeared;
     - .surface cards (#121829) came out DARKER than the ground they sat on, inverting
       elevation — cards are meant to lift off --bg, not sink into it;
     - every hover tint (.ch-row, .subj-card, .toc-link, .side-item) is var(--surface-2) too,
       so hovering a row that sits directly on the page produced no visible change.

   Transparent, not `background: var(--bg)`: the ground is stated once, on body, by the design
   system. Restating it here would be a second place to keep in sync. */
.fe-app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* The page column between the header and the footer. flex:1 is what pushes the footer to
   the bottom of a short page — FeLayout is a column flexbox — and min-width:0 stops a wide
   child (a chapter sheet's equation, a scrolling rail) from forcing the whole page wider
   than the viewport. */
.fe-main { flex: 1; min-width: 0; padding: 22px 0 56px; }

/* THE HEADER'S RULES ARE NO LONGER HERE. .fe-header, .fe-headbar, .fe-brand,
   .fe-brandmark, .fe-brandname, .fe-navlist, .fe-nav, .fe-pill, .fe-icobtn, .fe-divider,
   .fe-burger, .fe-menu, .fe-menurow, .fe-menuitem and .fe-menuitem-first drew the previous
   design's bar: 58px, opaque, on the admin portal's tokens, with a mint rounded-square brand
   mark, padded pill links and a text glyph for the theme toggle.

   FeHeader now renders the new design files' navbar and its rules are .nav / .nav-in /
   .brand / .brand-mark / .nav-links / .nav-tools / .theme-btn / .lang-btn in fe-ds.css,
   beside the rest of the design system. The burger and the slide-down menu keep their .fe-*
   names — those files have no mobile menu to name them after — but their rules moved there
   too, so the whole header is described in one place. */

/* -- Toast (F4) -----------------------------------------------------------------------
   A port of the prototype's inline toast (prototype.html:734). Fixed bottom-centre, on the
   --text-primary ground with --surface-primary text, so it inverts with the theme without
   naming a colour.

   left/transform rather than inset-inline: the pill is centred on the VIEWPORT, which has no
   reading direction, and a logical property here would do nothing but read as though it did.
   88vw keeps a long Urdu sentence off both edges on a 360px phone. */

.fe-toast {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 22px;
  z-index: 80;
  background: var(--fg);
  color: var(--surface);
  border-radius: 999px;
  padding: 12px 20px;
  font-family: var(--ui-font);
  font-size: 14px;
  line-height: var(--ui-tight);
  max-width: 88vw;
  text-align: center;
}

/* -- The "Solutions being added" empty state (R3) -------------------------------------
   Every unknown board/class/subject/chapter slug lands here. It is a product promise, not
   an error page: nothing on this site 404s. */

.fe-empty {
  margin-top: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 32px 22px;
  text-align: center;
}

.fe-empty-title {
  margin: 0;
  font-family: var(--ui-font);
  font-size: 16.5px;
  font-weight: 600;
  line-height: var(--ui-head);
  color: var(--fg);
}

.fe-empty-body {
  margin: 8px auto 0;
  font-family: var(--ui-font);
  font-size: 14px;
  line-height: var(--ui-line);
  color: var(--muted);
  max-width: 36rem;
}

.fe-empty-cta {
  display: inline-flex;
  align-items: center;
  margin-top: 18px;
  background: var(--surface);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 14.5px;
  font-weight: 600;
  line-height: var(--ui-tight);
  padding: 0 18px;
  min-height: 48px;
  white-space: nowrap;
  text-decoration: none;
}

/* -- Breakpoints ----------------------------------------------------------------------
   620px and 860px, exactly as the prototype defines them. Desktop is the primary design
   target (decision L10) but these two numbers do not move. */

@media (min-width: 620px) {

}

@media (min-width: 860px) {
  .fe-wrap { padding: 0 24px; }

  /* 276px rail — NOT the 200px the handoff claims (divergence D11). */
  .fe-reader { grid-template-columns: 276px minmax(0, 1fr); gap: 26px; }

  /* top: 92px clears the header plus the 4px progress bar and its breathing room. It was
     84px against the old 58px bar; the new design files' bar is 66px, so this moved with
     it — a rail that stops 8px too high tucks its first row under the header. */
  .fe-rail {
    order: 0;
    position: sticky;
    top: 92px;
    max-height: calc(100vh - 112px);
    overflow-y: auto;
  }

  /* Both halves of every visibility pair swap here. .nav-links is the .fe-navmob half's
     opposite number and is hidden by fe-ds.css below this width, so exactly one of the two
     is displayed at any width — the same guarantee, split across the two files that own
     each half. */
  .fe-navmob  { display: none; }
  .fe-toc     { display: block; }
  .fe-tocmob  { display: none; }

  /* Rail collapsed to a 76px icon strip — NOT 60px (divergence D10). Desktop only: on
     mobile the rail is a stacked block with nothing to collapse into. */
  .fe-reader.rail-off { grid-template-columns: 76px minmax(0, 1fr); gap: 18px; }
  .fe-reader.rail-off .fe-rail { padding: 10px 8px; }
  .fe-reader.rail-off .fe-full { display: none; }
  .fe-reader.rail-off .fe-mini { display: flex; }
}

/* -- Print ----------------------------------------------------------------------------
   A chapter sheet must print as one clean document: chrome, rail and controls all carry
   .no-print. Auditing that every one of them does is T8.4.

   THE SAVED FILE HAS TO LOOK LIKE THE SCREEN, and hiding the chrome is only the first
   third of that. F31 does not print, it SAVES: feInterop.print swaps document.title and
   calls window.print() so the reader can pick "Save as PDF". What comes back is a file
   they keep and read on a screen, not a sheet of paper — so the default print treatment,
   which is tuned for ink on white, is the wrong target. The three corrections below are
   what stood between the reader and a file that matches what they pressed the button on. */

@media print {
  .no-print { display: none !important; }

  /* 0 — THE SAVE PATH'S OPT-IN HALF. .no-print above is opt-OUT: anything added to a page
     prints unless somebody remembers to mark it, so one forgotten class puts site furniture
     in a reader's saved chapter and nothing anywhere fails. feInterop.print inverts that for
     the save path — it walks from [data-fe-print-root] up to <body> stamping this on every
     sibling, so only the chapter's own subtree survives into the file.

     DEFINED ONLY INSIDE @media print, which is what makes the stamping safe: the class is
     inert on screen, so a throw between adding it and removing it cannot leave a reader
     looking at a blank page. The rule is unscoped for the same reason the class is applied
     by hand — nothing outside that one function ever sets it. */
  .fe-print-away { display: none !important; }

  /* 1 — COLOUR. Engines drop background colours and images in print unless told not to,
     which on this site means the dark theme's near-white body text landing on white
     paper: a file that is not merely off-brand but unreadable. print-color-adjust is an
     inherited property, so stating it once on the root reaches everything; body carries
     the canvas colour explicitly because the propagated background is what the page box
     is painted from. Both spellings — the unprefixed property is still recent enough
     that the -webkit- alias is doing real work in installed browsers. */
  html[data-fe-site] {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  html[data-fe-site] body { background: var(--bg); }

  /* 2 — FULL BLEED IS NOT HERE, AND CANNOT BE. It needs @page { margin: 0 }, and @page takes
     no selector: this file loads on every page in the app, portal included, so an @page rule
     written here would silently strip the margins off every portal print too. That is exactly
     the cross-contamination the [data-fe-site] scoping everywhere else in this file exists to
     prevent, and it is the one rule that cannot be scoped.
     It is injected instead by feInterop.print, for the duration of the call and only when a
     fileName was passed — that is, only on the SAVE path. The F26 print button passes nothing
     and keeps the page's ordinary margins, which is right: it prints, it does not save. */

  /* 3 — THE RAIL'S COLUMN. .fe-rail carries .no-print, but the GRID TRACK it sat in does
     not: a print surface is about 816px wide, so the desktop rule above still matches and
     reserves 276px for an element that is no longer there. The sheet printed into the
     remainder with a quarter of every page blank. Both states are restated, because
     .rail-off sets its own narrower track. */
  .fe-reader,
  .fe-reader.rail-off {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  /* ONE QUESTION, ONE PIECE — WITHDRAWN (§16). `.q-card { break-inside: avoid }` used to live
     here, on the reasoning that a card kept whole is the closest paper gets to a screen. It
     cost more than it bought.

     A .q-card is the question AND its answer, and a typical one runs well over half a page.
     When a card that size does not fit in what is left of the current page, the engine obeys
     the rule the only way it can: it moves the WHOLE card to the next page and leaves the
     rest of this one blank. Readers were getting chapters with a third of every sheet white.

     The rule the chapter documents actually carry is `.qcard { page-break-inside: avoid }`,
     and their .qcard is only the tinted question block — tag, ayah, question — with the
     answer outside it. That is cheap to keep whole. fe-print.css puts it where it belongs,
     on .q-head and .q-ask, and lets the answer flow. */
}
