/* =====================================================================
   LinguaFace — IELTS visual identity
   =====================================================================

   Written 2026-08-17. This file exists so IELTS can stop borrowing TOEFL's
   look: the listing page used to @include('assets/css/toeflcss') outright,
   which is why the two sections were indistinguishable.

   TOEFL is deliberately untouched. It keeps exam.css and layouts/exam.blade.php;
   IELTS gets this file and layouts/ielts.blade.php. Same fork already proven for
   the SAT interface.

   PALETTE SOURCE -- REPLACED 2026-08-18
   This file used to carry a scholarly navy + citation gold palette taken from
   the UI-UX Pro Max colour data. THAT IDENTITY IS GONE. Ramal approved the
   TestGlider look for the whole IELTS experience, so every colour here is now
   one of TestGlider's own design tokens, dumped from :root on
   www.testglider.com on 2026-08-18. HANDOFF 10.20 records the instruction and
   10.18 has the measured component spec.

   HOW THE SWAP WAS DONE, and why it should be extended the same way:
   the token NAMES were left alone. ~200 var(--if-*) references and 140
   .ielts-page rules depend on them, and several of those rules style live exam
   controls -- .droplet-btn, .audio-player, .essay-textarea, the countdown.
   Re-pointing values re-skins the product without moving a selector. Do not
   "tidy" the --if-navy / --if-gold names to match their new values; the names
   are load-bearing and the mapping is commented at each one.

   THREE THINGS ARE DELIBERATE AND SHOULD NOT BE "FIXED":
     * The countdown and the on-dark primary are #FEC62E (TestGlider
       --speakingYellow), NOT their #175FFC. The blue measures 3.66:1 on the
       dark chrome and fails; the yellow is 11.97:1. This is the same trap the
       old palette hit and documented.
     * The exam chrome (navbar, timer, question navigator, review head) stays
       DARK, now #111114 instead of navy. TestGlider's site pages are all light,
       but their exam screens could not be inspected -- the account had a live
       unfinished attempt on every paper and resuming one to look would have run
       a real clock down. A dark exam bar is the safe, conventional choice and
       keeps the countdown contrast. Revisit only with their real exam UI in view.
     * The four paper colours are TestGlider's LIGHT variants with BLACK text,
       because that is what their skill cards actually do. They are not -700
       steps carrying white any more. Strong steps live in --if-*-ink for
       borders and meters, which the tints are too pale to serve.

   EVERYTHING IS SCOPED UNDER .ielts-page
   The listing renders through layouts/app.blade.php, which TOEFL and the
   homepage also use. Unscoped rules here would restyle those pages too -- the
   exact mistake this file exists to undo.
   ===================================================================== */

.ielts-page {
  /* ---- brand: TestGlider's own tokens, 2026-08-18 ----
     The navy/gold identity is GONE. Every value below is TestGlider's, dumped
     from :root on www.testglider.com and kept under a mapping comment so the
     provenance is legible. HANDOFF 10.20 records the instruction.

     The token NAMES are unchanged on purpose. ~200 var(--if-*) references and
     140 .ielts-page rules depend on them, several of them on live exam screens.
     Re-pointing the values re-skins everything without moving a single selector,
     which is the only safe way to restyle CSS that is serving a running test. */
  --if-navy:          #111114;   /* was #1E3A5F. TestGlider --black: dark chrome, headings */
  --if-navy-deep:     #000000;   /* gradient end, one step below --if-navy */
  --if-navy-soft:     #36373b;   /* TestGlider --almostBlack */
  --if-gold:          #175FFC;   /* TestGlider --readingBlue: the accent on light grounds */
  --if-gold-bright:   #FEC62E;   /* TestGlider --speakingYellow.
                                    This is the countdown and the on-dark primary.
                                    It is NOT --readingBlue, deliberately: #175FFC on
                                    #111114 measures 3.66:1 and fails, and HANDOFF 10.4
                                    fixed that exact bug once already. #FEC62E is 11.97:1
                                    on the dark chrome. Do not "correct" it to the blue. */

  /* ---- surfaces ---- */
  --if-bg:            #F7F9FB;   /* TestGlider --whiteBlue */
  --if-card:          #FFFFFF;   /* --white, unchanged */
  --if-fg:            #111114;   /* --black */
  --if-muted:         #F0F2F4;   /* their inactive-pill grey */
  --if-muted-fg:      #5B5C61;   /* --darkGray. 6.32:1 on --if-bg */
  --if-border:        #E8EAED;   /* --lightGray */
  --if-danger:        #D7000D;   /* --alertRed. white on it 5.39:1 */
  --if-success:       #1C6C00;   /* --expGreenDark. white on it 6.57:1 */

  /* ---- the four papers ----
     TestGlider tints its paper cards and puts BLACK on them; it never fills a
     badge with a saturated colour and puts white on it. These are the Light
     variants, measured off their live skill cards, and the badge rule below now
     carries black text to match. Black on each: 9.79 / 15.97 / 16.26 / 12.61. */
  --if-listening:     #FFA0B0;   /* --listeningRedLight */
  --if-reading:       #DEF876;   /* --readingLimeLight  */
  --if-writing:       #C6F7FC;   /* --writingCyanLight  */
  --if-speaking:      #FFCB74;   /* --speakingMangoLight */

  /* ---- tokens the ported TestGlider components need (HANDOFF 10.21) ----
     Kept close to TestGlider's own names so the ported rules stay recognisable
     against design/sat-landing-testglider.html, the reference specimen. */
  --if-r-stat:  20px;            /* their stat-panel radius */
  --if-card-ink:#222;            /* the ink they use on tinted cards */
  --if-blue-50: #F4F8FF;         /* --toeflBlue50 */
  --if-white-60:hsla(0,0%,100%,.6);
  --if-black-08:rgba(0,0,0,.08);
  --if-black-12:rgba(0,0,0,.12);
  --if-t-fast:  120ms;
  --if-t-med:   220ms;
  --if-ease:    cubic-bezier(.22,.61,.36,1);
  /* per-test pastels, sampled off their live cards */
  --tg-1:#FFCECB; --tg-2:#FFD7BA; --tg-3:#FFF0BD;
  --tg-4:#F1E5D7; --tg-5:#DDFBCD; --tg-6:#DFDAF8;

  /* Strong steps, for borders / meters / anything that needs to read as a line
     rather than a wash. The tints above are too pale for those. */
  --if-listening-ink: #E11F3E;   /* --listeningRed */
  --if-reading-ink:   #175FFC;   /* --readingBlue  */
  --if-writing-ink:   #8CE5EC;   /* --writingCyan  */
  --if-speaking-ink:  #FF9700;   /* --speakingMango */

  /* ---- scale ---- */
  /* TestGlider's radii, measured: pill 12, utility card 16, stat panel 20,
     big test/paper card 24. Rounder than the navy identity was. */
  --if-r-sm: 12px;
  --if-r:    16px;
  --if-r-lg: 24px;
  --if-s-1:  8px;
  --if-s-2:  12px;
  --if-s-3:  16px;
  --if-s-4:  24px;
  --if-s-5:  32px;
  --if-s-6:  48px;
  --if-shadow:    0 1px 2px rgba(17,17,20,.06), 0 4px 12px rgba(17,17,20,.06);
  --if-shadow-lg: 0 2px 4px rgba(17,17,20,.06), 0 12px 28px rgba(17,17,20,.10);

  background: var(--if-bg);
  color: var(--if-fg);
}

.ielts-page *,
.ielts-page *::before,
.ielts-page *::after { box-sizing: border-box; }

/* The listing sits on WHITE, not on --if-bg.
   Utility card 1 is #F7F9FB and .ielts-page is also #F7F9FB, so the card was
   invisible against its own page. Reference A's body is #FFFFFF and Reference
   B's listing is white too.
   Scoped to .ielts-listing DELIBERATELY: ielts.css is shared with the detail
   and exam screens, which keep #F7F9FB. Do not lift this onto .ielts-page. */
.ielts-page.ielts-listing { background: #FFFFFF; }

.ielts-shell {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 var(--if-s-3);
}

/* ---------------------------------------------------------------
   HERO and SKILL STRIP -- REMOVED 2026-08-18.

   Reference B (TestGlider's live IELTS listing) has neither: it runs from
   the sub-nav straight into the utility cards, measured at 1px, and it has
   no standalone paper cards anywhere on the listing. Both blocks and every
   rule that served only them are gone --
       .ielts-hero / -inner / -actions / h1 / p
       .ielts-eyebrow / ::before
       .ielts-btn / -primary / -ghost / :focus-visible
       .ielts-skills / .ielts-skill / -badge / -name / -meta / [data-skill]
   plus their @media overrides.

   The --skill custom property SURVIVES. The badge was only one consumer;
   .ielts-paper (detail) and .ielts-review (review) still read it, fed by
   .ielts-page.paper-* further down. Do not remove those.
   --------------------------------------------------------------- */

/* ---------------------------------------------------------------
   SECTION HEADINGS
   --------------------------------------------------------------- */
.ielts-section { margin-bottom: var(--if-s-6); }
.ielts-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--if-s-2);
  margin-bottom: var(--if-s-3);
}
.ielts-section-head h2 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--if-navy);
}
.ielts-section-head a {
  font-size: .875rem;
  font-weight: 600;
  color: var(--if-navy);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.ielts-tip {
  display: flex;
  gap: var(--if-s-2);
  padding: var(--if-s-2) var(--if-s-3);
  margin-bottom: var(--if-s-3);
  background: #F4F8FF;
  border: 1px solid #D6E3FE;
  border-left: 4px solid var(--if-gold);
  border-radius: var(--if-r-sm);
  font-size: .875rem;
  color: #0A369A;
}

/* ---------------------------------------------------------------
   TEST CARDS -- REPLACED 2026-08-18. The old horizontal row card (badge
   left, body, arrow right) is gone along with its markup; TestGlider uses
   a square tinted card. The replacement is the ported block at the end of
   this file. HANDOFF 10.21.
   --------------------------------------------------------------- */
.ielts-empty {
  padding: var(--if-s-5);
  text-align: center;
  color: var(--if-muted-fg);
  background: var(--if-card);
  border: 1px dashed var(--if-border);
  border-radius: var(--if-r);
}

/* ---------------------------------------------------------------
   BREAKPOINTS — mobile first, so these only widen the layout
   --------------------------------------------------------------- */
@media (min-width: 768px) {
  .ielts-shell { padding: 0 var(--if-s-4); }
}

/* Very narrow phones: keep the card readable rather than crushing the badge. */
@media (max-width: 380px) {
  .ielts-test { gap: var(--if-s-2); padding: var(--if-s-2); }
  .ielts-test-badge { width: 86px; }
  .ielts-test-name { font-size: .98rem; }
}

/* =====================================================================
   TEST SCREENS
   =====================================================================

   Everything below overrides exam.css, which layouts/ielts.blade.php loads
   first as a structural base. exam.css itself is never edited -- it is shared
   with TOEFL, and editing it is exactly what made the two products identical.

   Scope: every rule sits under .ielts-page, which layouts/ielts.blade.php puts
   on <body>. TOEFL's layout does not, so none of this can reach it. The prefix
   also raises specificity above exam.css's bare class selectors, which is what
   makes the override work without !important.
   ===================================================================== */

/* ---- the bar across the top of every test screen ---- */
.ielts-page .navbar {
  background: var(--if-navy);
  border-bottom: 1px solid var(--if-navy-deep);
  padding: 0 var(--if-s-3);
  min-height: 56px;
  display: flex;
  align-items: center;
  color: #fff;
}
.ielts-page .navbar a,
.ielts-page .navbar .x-of-y-question { color: #fff; }

/* Save & Exit, Next, Start, Submit */
.ielts-page .droplet-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.4);
  background: transparent;
  color: #fff;
  font-size: .8rem;
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  text-decoration: none;
}
.ielts-page .droplet-btn:hover { background: rgba(255,255,255,.12); color: #fff; }
.ielts-page .droplet-btn.info-next,
.ielts-page .droplet-btn.info-start,
.ielts-page .droplet-btn.submit {
  background: var(--if-gold-bright);
  border-color: var(--if-gold-bright);
  color: #111114;
}
.ielts-page .droplet-btn.info-next:hover,
.ielts-page .droplet-btn.info-start:hover,
.ielts-page .droplet-btn.submit:hover { background: #FFD75E; color: #111114; }
.ielts-page .droplet-btn.disabled,
.ielts-page .droplet-btn[disabled] { opacity: .45; pointer-events: none; }
.ielts-page .droplet-btn:focus-visible,
.ielts-page .squrelet-btn:focus-visible { outline: 3px solid var(--if-gold-bright); outline-offset: 2px; }

.ielts-page .x-of-y-question {
  font-size: .75rem;
  line-height: 1.25;
  text-align: center;
  color: #B8BCC0;
}
.ielts-page .x-of-y-question .current-question-number { color: var(--if-gold-bright); font-weight: 800; }
.ielts-page .rightside-buttons { display: flex; align-items: center; gap: var(--if-s-2); }

/* ---- the countdown: gold, tabular so the digits do not jitter ---- */
.ielts-page .test-timer-wrap { display: flex; align-items: center; gap: var(--if-s-1); }
.ielts-page .test-timer {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 104px;
  height: auto !important;
  padding: 6px 14px;
  border-radius: 999px;
  /* Was the OLD gold in rgba() form — a hex search does not find it, and this is
     the one element a candidate stares at under time pressure. */
  background: rgba(254,198,46,.14);       /* --speakingYellow at 14% */
  border: 1px solid rgba(254,198,46,.45);
  color: var(--if-gold-bright);
  font-size: 1rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}
.ielts-page .test-timer::before {
  content: "";
  width: 15px; height: 15px;
  flex: 0 0 auto;
  background: currentColor;
  -webkit-mask: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3 2'/%3E%3C/svg%3E");
          mask: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3 2'/%3E%3C/svg%3E");
}
/* under five minutes the clock turns red and pulses once a second */
.ielts-page .test-timer.is-low {
  background: rgba(215,0,13,.18);       /* --alertRed at 18% */
  border-color: rgba(252,159,165,.6);   /* --ieltsRed400 */
  color: #FC9FA5;                       /* --ieltsRed400 */
  animation: ielts-tick 1s steps(2, end) infinite;
}
@keyframes ielts-tick { 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) {
  .ielts-page .test-timer.is-low { animation: none; }
}

.ielts-page .squrelet-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 1px solid var(--if-border);
  background: var(--if-card);
  color: var(--if-navy);
  font-weight: 600;
}
.ielts-page .navbar .squrelet-btn {
  background: transparent;
  border-color: rgba(255,255,255,.35);
  color: #fff;
}

/* ---- instruction screens, shown before each paper ---- */
.ielts-page [data-intro-info] h3,
.ielts-page [data-section-info] h3 { color: var(--if-navy); }
.ielts-page [data-section-info] > div {
  max-width: 780px;
  margin: var(--if-s-5) auto;
  padding: var(--if-s-5) !important;
  background: var(--if-card) !important;
  border: 1px solid var(--if-border);
  border-top: 4px solid var(--skill, var(--if-navy));
  border-radius: var(--if-r);
  box-shadow: var(--if-shadow);
}
.ielts-page [data-section-info] p {
  margin-left: 0 !important;
  margin-right: 0 !important;
  color: var(--if-fg);
  max-width: 68ch;
}
.ielts-page [data-section-info] b { color: var(--if-navy); }

/* per-paper accent, set on <body> by each index view */
.ielts-page.paper-listening { --skill: var(--if-listening); }
.ielts-page.paper-reading   { --skill: var(--if-reading); }
.ielts-page.paper-writing   { --skill: var(--if-writing); }
.ielts-page.paper-speaking  { --skill: var(--if-speaking); }

/* ================================================================
   THE EXAM SHELL -- one viewport-high column, and it does not scroll
   ================================================================

   Rebuilt 2026-08-19. What was here before was not a column at all, and
   every symptom on the four test screens came out of that one fact:

     exam.css  .test-body { height: calc(100% - 130px) }   <- a 130px header
     ielts.css .reading-mcq { height: calc(100vh - 150px) } <- a 150px header
     ielts.css .ielts-nav  { position: sticky; bottom: 0 }

   The IELTS header is 90px, not 130 and not 150, so `.test-body` stopped 40px
   short of the viewport floor (the dead space under the left pane) while the
   panes it contained were 20px TALLER than it and spilled straight out the
   bottom.

   The navigator was worse. `position: sticky` is measured against the nearest
   SCROLLING ancestor but confined to its own containing block -- here the bare
   <div> from content.blade.php, which is only as tall as its contents. On the
   Reading paper that block ends 91px into the scroll, so the bar stayed at the
   viewport floor for exactly 91px and then rode up the page with the content,
   an opaque z-index:20 slab dragged across the answers. Measured before the
   fix: at 1247x900 the bar covered question 3's TRUE option and its radio
   input outright; at 1024x800, question 2's NOT GIVEN; at 375x720 it covered
   answers at 10 of 26 scroll positions. That is the "FALSE cannot be clicked"
   report, and it was never a z-index or an offset -- sticky simply cannot pin
   to a box that is not the scrollport.

   The document scrolled because of a third thing: `.mcq-body:has(> :only-child)`
   set `height: auto` to kill exam.css's dead 100px grid row, and in doing so
   beat the `height: 100%` that made the questions pane a scroller. The pane
   became 2262px of content inside a 443px box and pushed the whole document to
   2447px. Two panes with their own scrollbars, plus a page scrollbar, plus a
   navigator scrollbar.

   So: <body> is the column. Header, then one flex:1 region, then the
   navigator, which is now an ordinary last row and cannot overlap anything by
   construction. Percentage and 100vh heights are gone from the chain -- every
   height below here comes from the flex distribution, which is what makes the
   header's real height stop mattering.

   No !important anywhere, and nothing here reaches TOEFL.

   SCOPE: this block keys off `.ielts-exam`, NOT `.ielts-page`. `.ielts-page` is
   also set by mock-tests.blade.php, exam/detail.blade.php and review.blade.php,
   none of which is a test screen; turning those into 100vh flex columns would
   squash them, the review page worst of all. `.ielts-exam` is set only by
   layouts/ielts.blade.php, which only the five test screens extend. */

.ielts-page.ielts-exam {
  height: 100vh;
  height: 100dvh;                  /* mobile: the bar-less height, not the tall one */
  display: flex;
  flex-direction: column;
}

/* The header keeps whatever height its own content needs. Nothing else in this
   file may depend on that number ever again. */
.ielts-exam > .navbar { flex: 0 0 auto; }

/* exam.css makes this a grid at calc(100% - 130px). It is the column's body. */
.ielts-exam > .test-body {
  flex: 1 1 0;
  min-height: 0;                   /* without this a flex item refuses to shrink
                                      below its content and the overflow comes
                                      straight back */
  height: auto;
  display: flex;
  flex-direction: column;
}

/* content.blade.php wraps each paper in one bare <div>: info stage, question
   stage, navigator, spinner. It is the row that carries the navigator, so it
   has to be a column of exactly the height available -- this is the box that
   sticky was confined to before. */
.ielts-exam .test-body > div {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Whichever stage is on screen takes the space; .d-none removes the other. */
.ielts-exam [data-wrappers] {
  flex: 1 1 0;
  min-height: 0;
}
/* The instructions can be longer than the screen on a phone, so they scroll
   inside the region rather than growing the page. */
.ielts-exam [data-wrappers][data-info] { overflow-y: auto; }
.ielts-exam [data-wrappers][data-questions] {
  display: flex;
  flex-direction: column;
}

/* The root of the AJAX fragment, whatever each paper calls it:
   [data-reading-paper], [data-listening-part], the writing <form>,
   [data-speaking-question]. Speaking's hidden <input> is display:none and so
   is not a flex item. */
.ielts-exam [data-questions] > * {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Rows inside a fragment that keep their natural height. */
.ielts-exam .ielts-reading-tabs,
.ielts-exam .ielts-writing-tabs,
.ielts-exam [data-listening-part] > .recording-body,
.ielts-exam [data-listening-part] > hr { flex: 0 0 auto; }

/* ---- split panes: passage left, questions right ----

   The split belongs on `.reading-mcq`, which is the CONTAINER
   (passage | 5px divider | questions). `.reading` is one PANE inside it.

   These rules used to sit on `.reading`, which made each pane a two-column
   grid of its own children. On the Reading paper that put "Reading Passage 1"
   and the passage title in the left column and the "spend 20 minutes" line and
   the passage body in the right one, so the passage read out of order; the same
   happened to Listening's question groups. Meanwhile `.reading-mcq` kept
   exam.css's `1fr 5px 1fr` at every width, so on a 375px phone the passage
   column was 112px -- about fifteen characters. Both came from the one
   mix-up. */
.ielts-page .reading-mcq {
  display: grid;
  /* minmax(0, 1fr), not 1fr. A bare 1fr track will not go below the widest
     child's MIN-CONTENT width, and .essay-textarea has an intrinsic one (a
     textarea defaults to ~20 columns). Stacked at 375px that made the Writing
     pane 9px wider than the region holding it and gave the question stage a
     horizontal scrollbar of its own. Measured, not guessed: scrollWidth 354 vs
     clientWidth 345, and 345/345 with this. */
  grid-template-columns: minmax(0, 1fr);   /* phones first: stacked */
  gap: var(--if-s-3);
  align-items: start;
}
.ielts-page .reading {
  display: block;                  /* a pane, not a grid */
}

@media (max-width: 899px) {
  /* Stacked, there is no second pane to scroll against, so the question stage
     is the one scroller and the panes grow inside it. Two nested scroll areas
     on a phone is the thing HANDOFF §10.6 warned about. */
  .ielts-exam [data-wrappers][data-questions] { overflow-y: auto; }
  .ielts-exam [data-questions] > * { flex: 1 0 auto; min-width: 0; }
  .ielts-exam .reading-mcq { flex: 1 0 auto; }
  /* Same reason as the minmax(0, 1fr) above: let the panes shrink past their
     min-content width so the region never scrolls sideways. */
  .ielts-page .reading-mcq > * { min-width: 0; }
  .ielts-page .reading,
  .ielts-page [data-listening-part] > .reading {
    height: auto;
    overflow: visible;
    padding: var(--if-s-2);
  }
  /* the bare grey divider <div> between the panes has no height of its own;
     stacked, it would only contribute an empty gap row */
  .ielts-page .reading-mcq > [style*="gray"] { display: none; }
}

@media (min-width: 900px) {
  .ielts-page .reading-mcq {
    grid-template-columns: minmax(0, 1fr) 5px minmax(0, 1fr);
    /* One row, and it may shrink. An implicit `auto` row sizes to max-content
       and would spill the pane out of the bottom of the grid exactly the way
       the old calc(100vh - 150px) did. */
    grid-template-rows: minmax(0, 1fr);
    align-items: stretch;          /* `start` leaves the panes content-high */
    flex: 1 1 0;
    min-height: 0;
  }
  /* Each pane is its own scroller, and only its own. */
  .ielts-page .reading-mcq > * {
    min-height: 0;
    height: auto;                  /* the row supplies the height */
    overflow-y: auto;
  }
  /* Listening has no split: one recording, one column of notes. */
  .ielts-page [data-listening-part] > .reading {
    flex: 1 1 0;
    min-height: 0;
    height: auto;
    overflow-y: auto;
  }
}

/* exam.css lays .mcq-body/.scq-body out as three rows with a fixed 100px middle
   one, which TOEFL's markup fills. The IELTS reading paper puts a SINGLE child
   in there (passages-content renders the whole paper as one block), so rows two
   and three became 100px of dead space in the question pane -- most obvious on a
   phone, where it pushed the first question down the screen.

   `height: auto` here is what silently disabled the pane's own scrolling: it is
   one class more specific than `.reading-mcq > *` and so beat the `height: 100%`
   that rule used to carry. It is safe now only because the grid row stretches
   the pane to its full height, so `auto` and "the whole row" are the same thing.

   Scoped with :only-child on purpose: Listening's question-content genuinely
   fills all three rows and must keep the grid. */
.ielts-page .mcq-body:has(> :only-child),
.ielts-page .scq-body:has(> :only-child) {
  display: block;
  height: auto;
}
.ielts-page .reading-mcq,
.ielts-page .mcq-body {
  background: var(--if-card);
  border: 1px solid var(--if-border);
  border-radius: var(--if-r);
  padding: var(--if-s-3);
}
.ielts-page .scq-option {
  display: flex;
  align-items: flex-start;
  gap: var(--if-s-2);
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--if-border);
  border-radius: var(--if-r-sm);
  margin-bottom: var(--if-s-1);
  cursor: pointer;
}
.ielts-page .scq-option:hover { border-color: var(--if-reading-ink); background: #F4F8FF; }

/* ---- the numbered navigator along the bottom ----

   It is the last row of the shell column, not a sticky overlay. `position:
   sticky; bottom: 0` was the whole bug: sticky is confined to its containing
   block, that block was the paper wrapper rather than the scrollport, and past
   91px of scroll the bar detached and rode up over the answers. As an ordinary
   flex row it cannot overlap anything -- there is no scroll for it to fall out
   of, because the region above it is what scrolls.

   `position: relative` only so z-index still applies, which keeps the bar above
   anything a fragment positions absolutely. */
.ielts-page .ielts-nav {
  position: relative;
  flex: 0 0 auto;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--if-s-2);
  padding: var(--if-s-2) var(--if-s-3);
  background: var(--if-navy);
  border-top: 1px solid var(--if-navy-deep);
  /* Forty cells do not fit any laptop, so the bar scrolls sideways -- the same
     as TestGlider. overflow-y is pinned to hidden so the horizontal scrollbar
     can never provoke a vertical one inside a 56px bar. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}
.ielts-page .ielts-nav-group {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-right: var(--if-s-2);
  border-right: 1px solid rgba(255,255,255,.18);
}
.ielts-page .ielts-nav-group:last-child { border-right: 0; }
/* the part the candidate is actually in. Listening loads one part at a time, so
   without this the bar shows forty identical circles and gives no sense of
   where you are. */
.ielts-page .ielts-nav-group.is-current-part .ielts-nav-label { color: var(--if-gold-bright); }
.ielts-page .ielts-nav-group:not(.is-current-part) .ielts-nav-cell { opacity: .55; }
.ielts-page .ielts-nav-label {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #B8BCC0;
  white-space: nowrap;
  margin-right: 2px;
}
.ielts-page .ielts-nav-cell {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.35);
  background: transparent;
  color: #fff;
  font-size: .8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  cursor: pointer;
}
.ielts-page .ielts-nav-cell.answered { background: #fff; border-color: #fff; color: var(--if-navy); }
.ielts-page .ielts-nav-cell.current {
  background: var(--if-gold-bright);
  border-color: var(--if-gold-bright);
  color: #111114;
}
.ielts-page .ielts-nav-cell:focus-visible { outline: 3px solid var(--if-gold-bright); outline-offset: 2px; }

/* ---- passage tabs ---- */
.ielts-page .ielts-reading-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--if-s-1);
  margin-bottom: var(--if-s-2);
}
.ielts-page .ielts-reading-tabs .squrelet-btn.active {
  background: var(--if-navy);
  border-color: var(--if-navy);
  color: #fff;
}

/* ---- Writing: live word counter ---- */
.ielts-page .ielts-wordcount {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--if-muted);
  border: 1px solid var(--if-border);
  color: var(--if-muted-fg);
  font-size: .78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ielts-page .ielts-wordcount b { color: var(--if-navy); font-size: .9rem; }
.ielts-page .ielts-wordcount.is-under { border-color: #FDBBC0; background: #FFF5F7; color: #A60821; }
.ielts-page .ielts-wordcount.is-under b { color: #A60821; }
.ielts-page .ielts-wordcount.is-met { border-color: #D2FFC2; background: #F3FFEE; color: #1C6C00; }
.ielts-page .ielts-wordcount.is-met b { color: #1C6C00; }

/* ---- narrow screens: the bar has to stay usable ----

   Rewritten 2026-08-19. §10.23 fixed the exam shell but left the header
   overflowing: at 375px `.rightside-buttons` needed 324.7px and the row holding
   it was 336px wide, with Save & Exit and "Answered 0 of 40" (207.4px on
   Reading) already in it. Measured total 585.5px in 336px. That pushed the
   DOCUMENT sideways to 597px, and the horizontal scrollbar then stole 15px of
   height and forced a vertical one too — the ~15px of residual mobile scroll
   §10.23 reported and deliberately did not fix.

   Three things were fighting the wrap, and all three are exam.css's:

     .navbar             { height: 90px }        a hard height, so wrapped rows
                                                 spilled out of the bar
     .navbar > div       inline style, display:flex, no flex-wrap
     .droplet-btn-wrap   { width: 100% }         forced Submit onto a row of its
                                                 own, making the bar 150px tall

   None of them can be edited — exam.css is TOEFL's. All three are reachable
   from here instead: `flex-wrap` is absent from the inline style so CSS still
   wins on it, and the other two are plain class rules this file outranks.

   Result at 375x720, measured on all four papers: 375/375 and 720/720, no
   control out of bounds, none failing a hit-test, none under 24px, and the
   navigator still pinned to the floor. The bar is 104-108px instead of 90,
   which the shell absorbs because the header is `flex: 0 0 auto` and the panes
   take what is left.

   Scoped .ielts-exam, not .ielts-page: `.navbar` is ALSO the class on the site
   header in partials/header.blade.php, and only the exam layout sets
   .ielts-exam. */
@media (max-width: 640px) {
  .ielts-page .navbar { flex-wrap: wrap; gap: var(--if-s-1); padding: var(--if-s-1) var(--if-s-2); }
  /* exam.css pins this to 90px, which a wrapped bar cannot honour */
  .ielts-exam .navbar { height: auto; min-height: 56px; align-items: center; }
  .ielts-page .navbar > div { width: 100%; }
  .ielts-exam .navbar > div { flex-wrap: wrap; gap: var(--if-s-1); align-items: center; }
  .ielts-exam .navbar > div > * { min-width: 0; }
  /* Save & Exit and the answered count take the first row; the controls take
     the second, right-aligned, wrapping among themselves if they must. */
  .ielts-exam .rightside-buttons {
    flex: 1 0 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--if-s-1);
    width: auto;
  }
  /* exam.css gives this width:100%, which put Submit on a third row on its own
     and cost 43px of a 720px screen for one 50px button. */
  .ielts-exam .rightside-buttons .droplet-btn-wrap { width: auto; flex: 0 0 auto; }
  .ielts-exam .test-timer-wrap { flex-wrap: wrap; justify-content: flex-end; }
  .ielts-page .test-timer { min-width: 92px; font-size: .95rem; }
  .ielts-page .droplet-btn { padding: 8px 12px; font-size: .75rem; }
  .ielts-page .ielts-nav-cell { width: 30px; height: 30px; }
}

/* ===============================================================
   SITE PAGES  —  section switcher, exam detail
   Added 2026-08-17, when detail/index/records dropped toeflcss.
   =============================================================== */

/* ---------------------------------------------------------------
   THE IELTS SITE HEADER  —  added 2026-08-19
   ---------------------------------------------------------------

   Markup: frontend/partials/header-ielts.blade.php, a fork of the shared
   header. See that file for why it is a fork rather than an edit.

   These rules sit OUTSIDE .ielts-page on purpose: the header is a sibling of
   the page wrapper, not a descendant, so it cannot inherit the custom
   properties declared on .ielts-page. Every colour here is literal, as the
   .ielts-switch rules below already were, and must stay in step with the tokens
   at the top of this file. The `ielts-head*` prefix is what keeps them off
   TOEFL and the homepage, which render the ORIGINAL header — no class below is
   used by any other markup in the project.

   Values are TestGlider's own, measured on
   www.testglider.com/ielts/en/mock-tests/1 at a 1280px viewport. Where the live
   site and design/sat-landing-testglider.html disagreed, the live site won, per
   the client's instruction; the mockup's value is noted next to each so the
   divergence is legible rather than looking like a mistake. */

.ielts-head { position: sticky; top: 0; z-index: 11; background: #FFFFFF; }
.ielts-head-main { border-bottom: 1px solid #E8EAED; }
.ielts-head-shell {
  width: 100%;
  max-width: 1280px;      /* their .max-w-1280 */
  margin: 0 auto;
  padding: 0 40px;        /* their .px-40 */
}
.ielts-head-main .ielts-head-shell {
  display: flex;
  align-items: center;
  gap: 16px;              /* live 16. mockup said 16 on .brand but 6/16 elsewhere */
  min-height: 52px;       /* live 52. MOCKUP SAID 64 */
  padding-top: 6px;
  padding-bottom: 6px;
}

/* The logo keeps app.css's .navbar-logo sizing untouched — 50px. It is the one
   element the client asked not to change, so nothing here sets its size. */
.ielts-head-brand { flex: 0 0 auto; text-decoration: none; }

.ielts-head-product { font-size: 16px; font-weight: 600; color: #111114; }
.ielts-head-partner {
  font-size: 12px;
  color: #8A8C91;
  white-space: nowrap;
}
.ielts-head-partner b { color: #36373B; font-weight: 700; }

.ielts-head-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;               /* live 8. MOCKUP SAID 22 */
}
.ielts-head-link {
  font-size: 13px;        /* live 13. MOCKUP SAID 14 */
  font-weight: 600;       /* live 600. MOCKUP SAID 500 */
  color: #4A4B4D;         /* live #4A4B4D. MOCKUP SAID #36373b */
  padding: 6px 16px;      /* live 6/16. the mockup had none */
  text-decoration: none;
  border-radius: 9999px;
  transition: color 120ms ease, background-color 120ms ease;
}
a.ielts-head-link:hover { color: #175FFC; background: #F7F9FB; }
.ielts-head-sep {
  width: 1px;
  height: 12px;           /* live 12. MOCKUP SAID 14 */
  background: #E8EAED;
  flex: 0 0 auto;
}
.ielts-head-purchase {
  background: #175FFC;
  color: #FFFFFF;
  font-weight: 600;       /* live 600. MOCKUP SAID 700 */
  font-size: 14px;
  padding: 8px 16px;      /* live 8/16. MOCKUP SAID 9/22 */
  border-radius: 9999px;
  border: 0;
  white-space: nowrap;
}
.ielts-head-avatar {
  padding: 0;
  width: 40px; height: 40px;      /* live 40. MOCKUP SAID 36 */
  border-radius: 50%;
  border: 1px solid #E8EAED;
  background: #FFFFFF;
  color: #175FFC;                 /* live: the person mark is BLUE, not dark */
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  text-decoration: none;
  transition: border-color 120ms ease;
}
.ielts-head-avatar:hover { border-color: #B8BCC0; color: #175FFC; }
.ielts-head-avatar svg { width: 20px; height: 20px; }

/* Controls with no destination. They are deliberately not links: there is no
   reviews table, no community and no purchase flow anywhere in this codebase,
   and pointing them at "#" would advertise pages that do not exist. */
.ielts-head-link[aria-disabled="true"],
.ielts-head-purchase[aria-disabled="true"] { opacity: .45; cursor: default; }

.ielts-head :focus-visible { outline: 3px solid #175FFC; outline-offset: 2px; border-radius: 6px; }

/* ---- the sub-nav row ---- */
.ielts-subnav { background: #FFFFFF; border-bottom: 1px solid #E8EAED; }
.ielts-subnav-row {
  display: flex;
  gap: 16px;              /* live 16. MOCKUP SAID 24 */
  overflow-x: auto;
  scrollbar-width: none;
}
.ielts-subnav-row::-webkit-scrollbar { display: none; }

/* The class is `ielts-switch`, not `toefl-switch`: TOEFL's own navbar still uses
   `toefl-switch` and must keep it, and an unscoped rule on that shared name
   would have restyled TOEFL's switcher too. Restyled 2026-08-19 from 700/6px-2px
   to TestGlider's measured 600/16px-8px with the 2px underline. */
.ielts-switch {
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  color: #111114;
  padding: 16px 8px;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color 120ms ease, border-color 120ms ease;
}
a.ielts-switch:hover       { color: #175FFC; }
.ielts-switch[on="yes"]    { color: #175FFC; border-bottom-color: #175FFC; }
.ielts-switch:focus-visible{ outline: 3px solid #175FFC; outline-offset: 2px; }
.ielts-switch[aria-disabled="true"] { opacity: .45; cursor: default; }

@media (max-width: 900px) {
  /* the partner lockup and the secondary links are the first things TestGlider
     drops at narrow widths, and the mockup does the same at 720 */
  .ielts-head-partner,
  .ielts-head-link,
  .ielts-head-sep { display: none; }
  .ielts-head-shell { padding: 0 16px; }
}

/* ---- exam detail: breadcrumb ---- */
.ielts-page .ielts-detail { padding-top: var(--if-s-5); padding-bottom: var(--if-s-6); }

.ielts-page .ielts-crumb {
  display: flex; flex-wrap: wrap; gap: .4rem;
  font-size: .8125rem; color: var(--if-muted-fg);
  margin-bottom: var(--if-s-3);
}
.ielts-page .ielts-crumb a { color: var(--if-muted-fg); text-decoration: none; }
.ielts-page .ielts-crumb a:hover { color: var(--if-navy); text-decoration: underline; }
.ielts-page .ielts-crumb [aria-current] { color: var(--if-navy); font-weight: 700; }

/* ---- exam detail: the test-name banner ----

   Rebuilt 2026-08-19 from TestGlider's REAL detail page
   (www.testglider.com/ielts/en/mock-tests/1), measured at 1280px, not from the
   mockup — the mockup has no detail page at all.

   What replaced what: the navy gradient hero with its gold "IELTS ACADEMIC"
   kicker and description is gone, and so is the row of five flat white cards
   with thin coloured top borders. Their page is a blush name banner, then ONE
   full-width Full Test card, then a 2x2 grid of tinted paper cards.

   Everything here is under `.ielts-page.ielts-detail-page`, the same
   scoped-modifier pattern `.ielts-page.ielts-listing` uses (HANDOFF 10.22):
   ielts.css is shared with the listing and the live exam screens, so a bare
   `.ielts-page` rule would reach both. */
.ielts-page.ielts-detail-page .ielts-detail-name {
  display: flex;
  align-items: center;
  gap: var(--if-s-4);
  background: #FFCECB;                  /* their banner, sampled */
  border-radius: 48px;                  /* measured: 48, not the cards' 24 */
  padding: 0 48px;
  min-height: 160px;                    /* measured */
  overflow: hidden;
}
.ielts-page.ielts-detail-page .ielts-detail-name-text { flex: 1 1 auto; min-width: 0; }
.ielts-page.ielts-detail-page .ielts-detail-title {
  margin: 0;
  color: #111114;
  line-height: 1.15;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 700;
  letter-spacing: -.02em;
}
/* Our own artwork, kept: TestGlider's banner carries nothing but the name, but
   the city badge is IELTS's identity here and the listing cards use it too. */
.ielts-page.ielts-detail-page .ielts-detail-badge {
  flex: 0 0 auto;
  width: 180px; height: 112px;
  border-radius: var(--if-r);
  overflow: hidden;
  box-shadow: 0 8px 20px -10px var(--if-black-12);
}
.ielts-page.ielts-detail-page .ielts-detail-badge img {
  display: block; width: 100%; height: 100%; object-fit: cover;
}

/* ---- exam detail: the paper cards ----

   Full Test spans both columns; the four papers sit under it 2x2. Measured on
   their page: cards 386x200 with a 28px gap, radius 24, padding 24. */
.ielts-page.ielts-detail-page .ielts-papers-title {
  margin: var(--if-s-5) 0 var(--if-s-3);
  font-size: 1.125rem;
  color: var(--if-fg);
}
.ielts-page.ielts-detail-page .ielts-papers {
  display: grid;
  grid-template-columns: minmax(0, 1fr);      /* phones first: stacked */
  gap: 28px;
}
@media (min-width: 760px) {
  .ielts-page.ielts-detail-page .ielts-papers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ielts-page.ielts-detail-page .ielts-paper.is-full { grid-column: 1 / -1; }
}

.ielts-page.ielts-detail-page .ielts-paper {
  /* One token for the lane the coin occupies, so the coin size and the space
     the name must keep clear of it cannot drift apart. Measured: at 780-1024px
     the cards narrow to ~340px and "Reading-Academic" ran straight under the
     coin without this. */
  --coin: 156px;
  position: relative;
  overflow: hidden;
  min-height: 200px;
  padding: 24px;
  border-radius: 24px;
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: #111114;
  background: var(--skill, var(--if-muted));
  transition: transform var(--if-t-med) var(--if-ease), box-shadow var(--if-t-med) var(--if-ease);
}
.ielts-page.ielts-detail-page .ielts-paper:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 36px -18px var(--if-black-12);
  color: #111114;
}
.ielts-page.ielts-detail-page .ielts-paper:focus-visible { outline: 3px solid #111114; outline-offset: 3px; }

.ielts-page.ielts-detail-page .ielts-paper-name {
  position: relative;
  z-index: 1;
  padding-right: calc(var(--coin) + 16px);   /* keep clear of the coin */
  font-size: 28px;                       /* measured */
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -.01em;
  margin: 0;
}

/* The white "coins". Theirs are 3D renders bleeding off the card's right edge;
   ours put the paper artwork we already ship inside the same white disc. */
.ielts-page.ielts-detail-page .ielts-paper-coin {
  position: absolute;
  right: 24px;
  top: 50%;
  transform: translateY(-50%);
  width: var(--coin); height: var(--coin);
  border-radius: 50%;
  background: #FFFFFF;
  display: grid;
  place-items: center;
  box-shadow: 0 10px 26px -12px rgba(0,0,0,.28);
  pointer-events: none;
}
.ielts-page.ielts-detail-page .ielts-paper-coin img {
  width: 62%; height: 62%; object-fit: contain; display: block;
}

/* Full Test: four coins fanned out, overlapping, right-aligned — their layout.
   Later coins sit further right and further back, so the first reads on top. */
/* The fan is four 132px coins overlapping by 46, so it occupies 390px. */
.ielts-page.ielts-detail-page .ielts-paper.is-full { background: #FFF5F7; --coin: 390px; }
.ielts-page.ielts-detail-page .ielts-paper-coins {
  position: absolute;
  right: 24px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  pointer-events: none;
}
.ielts-page.ielts-detail-page .ielts-paper-coins .ielts-paper-coin {
  position: static;
  transform: none;
  width: 132px; height: 132px;
  margin-left: -46px;                    /* the overlap */
}
.ielts-page.ielts-detail-page .ielts-paper-coins .ielts-paper-coin:first-child { margin-left: 0; }

/* ---- status pills: real attempt state, never a difficulty label ---- */
.ielts-page.ielts-detail-page .ielts-paper-status {
  position: relative;
  z-index: 1;
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;                              /* measured */
}
.ielts-page.ielts-detail-page .ielts-pill {
  background: #FFFFFF;
  border-radius: 12px;                   /* measured */
  padding: 2px 8px;                      /* measured */
  font-size: 12px;
  font-weight: 500;
  color: var(--if-muted-fg);             /* #5B5C61, their pill ink */
  white-space: nowrap;
}

/* per-paper tint, the same four tokens the test screens and the rail use */
.ielts-page.ielts-detail-page .ielts-paper.is-reading   { --skill: var(--if-reading); }
.ielts-page.ielts-detail-page .ielts-paper.is-listening { --skill: var(--if-listening); }
.ielts-page.ielts-detail-page .ielts-paper.is-writing   { --skill: var(--if-writing); }
.ielts-page.ielts-detail-page .ielts-paper.is-speaking  { --skill: var(--if-speaking); }

@media (max-width: 640px) {
  .ielts-page.ielts-detail-page .ielts-detail-name { padding: 0 24px; min-height: 132px; }
  .ielts-page.ielts-detail-page .ielts-detail-badge { width: 108px; height: 68px; }
  .ielts-page.ielts-detail-page .ielts-paper { --coin: 112px; }
  .ielts-page.ielts-detail-page .ielts-paper-coin { right: 16px; }
  .ielts-page.ielts-detail-page .ielts-paper-name { font-size: 22px; }

  /* Full Test STACKS on a phone. Four coins cannot share a row with the name in
     a 312px card whatever size they are -- reserving their lane left 52px for
     the title. Name, then the fan right-aligned beneath it, then the pills. */
  .ielts-page.ielts-detail-page .ielts-paper.is-full { --coin: 0px; }
  .ielts-page.ielts-detail-page .ielts-paper.is-full .ielts-paper-name { padding-right: 0; }
  .ielts-page.ielts-detail-page .ielts-paper-coins {
    position: static;
    transform: none;
    align-self: flex-end;
    margin: 12px 0;
  }
  .ielts-page.ielts-detail-page .ielts-paper-coins .ielts-paper-coin { width: 76px; height: 76px; margin-left: -26px; }

  /* The logo is 189px wide and must not be resized (client instruction), so at
     this width the header row wraps instead: brand on the first line, Purchase
     and the avatar on the second. Without this the right group overflowed to
     434px in a 360px viewport and the whole page scrolled sideways. */
  .ielts-head-main .ielts-head-shell { flex-wrap: wrap; }
}

@media (prefers-reduced-motion: reduce) {
  .ielts-page.ielts-detail-page .ielts-paper { transition: none; }
  .ielts-page.ielts-detail-page .ielts-paper:hover { transform: none; }
}

/* ===============================================================
   TEST SCREENS  —  Listening, Writing, Speaking
   Added 2026-08-17. Until now these three papers were still drawn by
   exam.css, so a candidate met three different palettes in one exam:
     Listening  play button   rgb(80,118,203)   TOEFL blue
     Speaking   record/stop   #175FFC           a third blue
     everything else          IELTS navy + gold
   Selectors below are deliberately one step more specific than exam.css's
   (.ielts-page .audio-container .play-btn beats .audio-container .play-btn)
   rather than relying on load order alone.
   =============================================================== */

/* exam.css makes .test-body a grid, and its single implicit column sizes to
   max-content. So the widest descendant set the width of the whole page: the
   400px recording frame plus the mic-test container's 30px padding came to
   463px, and a 375px phone got a horizontal scrollbar with every screen
   dragged sideways. min-width:0 is what lets the children shrink below their
   content.

   The `grid-template-columns: minmax(0, 1fr)` half of that fix was dropped
   2026-08-19: .test-body is a flex column now (see THE EXAM SHELL above), so
   there is no grid column left to constrain and the declaration was inert. The
   min-width:0 still does the work, on the flex axis instead. */
.ielts-page .test-body > * { min-width: 0; }

/* Form controls. Neither stylesheet declared a colour-scheme, so on a browser
   set to dark mode Chrome drew the essay textarea with its dark UA default --
   #36373B with white text -- inside an otherwise white page. That is a UA
   default, not TOEFL styling (exam.css sets no textarea colour and TOEFL is
   affected identically). Declaring the scheme and the colours makes the paper
   look the same for every candidate. */
.ielts-page { color-scheme: light; }

.ielts-page textarea,
.ielts-page input[type="text"],
.ielts-page input[type="search"] {
  background: var(--if-card);
  color: var(--if-fg);
  border: 1px solid var(--if-border);
  border-radius: var(--if-r-sm);
  font: inherit;
  padding: 8px 10px;
}
.ielts-page textarea:focus,
.ielts-page input[type="text"]:focus {
  outline: 3px solid var(--if-gold-bright);
  outline-offset: 1px;
  border-color: var(--if-navy);
}

/* ---------------------------------------------------------------
   LISTENING
   --------------------------------------------------------------- */
.ielts-page .audio-container .play-btn,
.ielts-page .play-question-audio-btn {
  background: var(--skill, var(--if-listening));
  color: #fff;
  border: 0;
  border-radius: 999px;
  padding: 10px 20px;
  min-height: 44px;                 /* touch target */
  font-size: .95rem;
  font-weight: 700;
  cursor: pointer;
}
.ielts-page .audio-container .play-btn:hover,
.ielts-page .play-question-audio-btn:hover { filter: brightness(1.08); }
.ielts-page .audio-container .play-btn:focus-visible,
.ielts-page .play-question-audio-btn:focus-visible {
  outline: 3px solid var(--if-gold-bright); outline-offset: 2px;
}

.ielts-page .audio-container .audio-progress meter { accent-color: var(--if-reading-ink); }
.ielts-page .listening-qa { gap: var(--if-s-2); }
.ielts-page .scq-question { font-size: 1rem; line-height: 1.6; }
.ielts-page .scq-answer   { gap: var(--if-s-1); }

/* exam.css pins this to a fixed 400x300, which overflows a 375px phone */
.ielts-page .recording-img-frame {
  width: 100%;
  max-width: 400px;
  height: auto;
  aspect-ratio: 4 / 3;
  margin-inline: auto;
  border-radius: var(--if-r);
  overflow: hidden;
}
.ielts-page .recording-img { border-radius: var(--if-r); }

/* ---------------------------------------------------------------
   WRITING
   --------------------------------------------------------------- */
.ielts-page .essay-textarea,
.ielts-page .discuss-textarea {
  min-height: 16rem;
  line-height: 1.6;
  border-radius: var(--if-r-sm);
}
.ielts-page .essay-title { font-weight: 700; color: var(--if-navy); }
.ielts-page .essay-title-n-word-count {
  align-items: baseline;
  gap: var(--if-s-2);
  padding-bottom: var(--if-s-1);
}
.ielts-page .word-count { font-size: .8125rem; color: var(--if-muted-fg); gap: .35rem; }
.ielts-page .word-count-value { font-weight: 700; color: var(--if-navy); }
.ielts-page .wread-timer {
  display: inline-flex; align-items: baseline; gap: .4rem;
  padding: 6px 12px;
  background: var(--if-muted);
  border-radius: 999px;
  font-size: .8125rem; color: var(--if-navy);
}
.ielts-page .wread-timer-title { color: var(--if-muted-fg); }
.ielts-page .wread-timer-time  { font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------
   SPEAKING
   --------------------------------------------------------------- */
/* exam.css gives these `max-width:700px; margin:auto`. As grid items of
   .test-body, `margin:auto` replaces the default stretch alignment, so the box
   sizes to its max-content instead of the track -- 463px against a 375px
   column, which is what actually forced the horizontal scrollbar on Speaking.
   width:100% puts it back on the track; max-width still caps it on a desktop. */
.ielts-page .speaking-before-start-container,
.ielts-page .speaking-microphone-test-container {
  width: 100%;
  max-width: 700px;
}
.ielts-page .speaking-before-start-container .instructions,
.ielts-page .speaking-microphone-test-container .instructions { line-height: 1.65; }

@media (max-width: 640px) {
  .ielts-page .speaking-before-start-container,
  .ielts-page .speaking-microphone-test-container { padding: var(--if-s-3); }
}

/* `.card` is scoped to the Speaking containers deliberately. It is also a
   BOOTSTRAP class, and the review page is built on Bootstrap cards with `p-4`
   spacing utilities -- a bare `.ielts-page .card` rule (0,2,0) would outrank
   `p-4` (0,1,0) and quietly re-space every card on that page. */
.ielts-page .checklist,
.ielts-page .speaking-before-start-container .card,
.ielts-page .speaking-microphone-test-container .card {
  background: var(--if-card);
  border: 1px solid var(--if-border);
  border-radius: var(--if-r);
  padding: var(--if-s-3);
  box-shadow: var(--if-shadow);
}
.ielts-page .prompt { font-size: 1rem; line-height: 1.6; color: var(--if-fg); }

/* the mic-test and answer controls: exam.css gives these #175FFC */
.ielts-page .speaking-microphone-test-container .play-btn,
.ielts-page .audio-player .play-btn,
.ielts-page [data-record-toggle].play-btn {
  background: var(--skill, var(--if-speaking));
  color: #fff;
  border: 0;
  min-height: 44px;
  border-radius: 999px;
  padding: 10px 20px;
  font-weight: 700;
  cursor: pointer;
}
.ielts-page .speaking-microphone-test-container .recorder-ui .stop-btn,
.ielts-page .stop-btn {
  background: var(--if-danger);
  color: #fff;
  border: 0;
  min-height: 44px;
  border-radius: 999px;
  padding: 10px 20px;
  font-weight: 700;
  cursor: pointer;
}
.ielts-page .speaking-microphone-test-container .play-btn:focus-visible,
.ielts-page .stop-btn:focus-visible,
.ielts-page [data-record-toggle].play-btn:focus-visible {
  outline: 3px solid var(--if-gold-bright); outline-offset: 2px;
}

/* exam.css reaches these through
   `.speaking-microphone-test-container .recorder-ui .status-bar` (0,3,0), so a
   two-class rule here loses no matter which file loads last. Matched depth for
   depth, with a plain fallback for any other context. Its `padding: 1rem 6rem`
   is also why the bar could not fit a phone. */
.ielts-page .speaking-microphone-test-container .recorder-ui .status-bar,
.ielts-page .status-bar {
  background: var(--if-muted);
  border-radius: 999px;
  padding: 8px 16px;
  gap: var(--if-s-1);
  color: var(--if-navy);
}
.ielts-page .speaking-microphone-test-container .recorder-ui .recording-label,
.ielts-page .recording-label { font-weight: 700; color: var(--if-danger); }
.ielts-page .speaking-microphone-test-container .recorder-ui .time-indicator,
.ielts-page .time-indicator  { font-variant-numeric: tabular-nums; color: var(--if-navy); }
.ielts-page .prep-speak-row,
.ielts-page .speak-time { color: var(--if-muted-fg); font-variant-numeric: tabular-nums; }

/* ---- narrow screens ---- */
@media (max-width: 640px) {
  .ielts-page .audio-container .play-btn,
  .ielts-page .speaking-microphone-test-container .play-btn,
  .ielts-page .stop-btn { width: 100%; }
  .ielts-page .essay-textarea { min-height: 12rem; }
}

/* ===============================================================
   REVIEW / RESULTS PAGE
   Added 2026-08-17. review.blade.php is a standalone document -- it never
   loaded toeflcss, but it had no IELTS identity either: Bootstrap defaults
   plus a small inline <style>, so a candidate finished an IELTS paper styled
   navy and gold and landed on a generic Bootstrap page.

   Bootstrap stays: the question navigator uses its tab JS (data-bs-toggle),
   and the partials are built on its grid. These rules sit over the top and
   are scoped to .ielts-review so they cannot reach anything else. Nothing here
   overrides a Bootstrap spacing utility (p-4, mb-3 and friends keep working).
   =============================================================== */

.ielts-review { padding-bottom: var(--if-s-6); }

/* ---- header: back, paper, score ---- */
.ielts-review-head {
  background: linear-gradient(135deg, var(--if-navy) 0%, var(--if-navy-deep) 100%);
  color: #fff;
  padding: var(--if-s-4) 0;
  margin-bottom: var(--if-s-4);
}
.ielts-review-head-inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--if-s-3);
  max-width: 1120px; margin: 0 auto; padding: 0 var(--if-s-3);
}
.ielts-review-back {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 44px;
  color: #B8BCC0; text-decoration: none; font-weight: 600; font-size: .875rem;
}
.ielts-review-back:hover { color: #fff; }
.ielts-review-back:focus-visible { outline: 3px solid var(--if-gold-bright); outline-offset: 2px; }

.ielts-review-paper {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: 6px 14px; border-radius: 999px;
  background: var(--skill, var(--if-navy-soft));
  color: #fff; font-weight: 700; font-size: .8125rem;
  letter-spacing: .04em; text-transform: uppercase;
}
.ielts-review-score { margin-left: auto; text-align: right; line-height: 1.1; }
.ielts-review-score b {
  display: block;
  font-size: clamp(1.5rem, 5vw, 2rem);
  color: var(--if-gold-bright);
  font-variant-numeric: tabular-nums;
}
.ielts-review-score span { font-size: .75rem; color: #B8BCC0; text-transform: uppercase; letter-spacing: .08em; }

/* per-paper accent, mirroring the test screens */
.ielts-review.paper-reading   { --skill: var(--if-reading); }
.ielts-review.paper-listening { --skill: var(--if-listening); }
.ielts-review.paper-writing   { --skill: var(--if-writing); }
.ielts-review.paper-speaking  { --skill: var(--if-speaking); }

/* ---- question navigator ----
   Up to 40 buttons. A flex row with gap ran off the side of a phone, so this
   wraps into a grid of fixed cells instead. */
.ielts-review-nav {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
  gap: var(--if-s-1);
  max-width: 1120px;
  margin: 0 auto var(--if-s-4);
  padding: 0 var(--if-s-3);
}
.ielts-review-nav .btn {
  min-width: 44px; min-height: 44px;      /* touch target */
  padding: 0;
  border-radius: var(--if-r-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--if-border);
  background: var(--if-card);
  color: var(--if-fg);
}
.ielts-review-nav .btn-outline-success { border-color: var(--if-success); color: var(--if-success); }
.ielts-review-nav .btn-outline-danger  { border-color: var(--if-danger);  color: var(--if-danger); }
.ielts-review-nav .btn.active,
.ielts-review-nav .btn-outline-success.active { background: var(--if-success); border-color: var(--if-success); color: #fff; }
.ielts-review-nav .btn-outline-danger.active  { background: var(--if-danger);  border-color: var(--if-danger);  color: #fff; }
.ielts-review-nav .btn:focus-visible { outline: 3px solid var(--if-gold-bright); outline-offset: 2px; }

/* ---- the answer cards (Bootstrap markup, IELTS surface) ---- */
.ielts-review .card {
  border: 1px solid var(--if-border);
  border-radius: var(--if-r);
  box-shadow: var(--if-shadow);
}
.ielts-review .badge.bg-success { background: var(--if-success) !important; }
.ielts-review .badge.bg-danger  { background: var(--if-danger)  !important; }
.ielts-review .badge.bg-info    { background: var(--if-writing) !important; }
.ielts-review .badge.bg-warning { background: var(--if-speaking) !important; color: #fff !important; }

/* The answer boxes in the reading + listening partials. These four rules were
   an inline <style> block in review.blade.php; they live here now so the page
   has one source of colour rather than two. Behaviour is unchanged apart from
   the palette: Bootstrap's #175FFC rule on .explanation-card became gold, and
   the green/red pair became the IELTS tokens. */
.ielts-review .answer-choice {
  border: 1px solid var(--if-border);
  border-radius: var(--if-r-sm);
  padding: .75rem;
  cursor: pointer;
  transition: background-color .2s ease-in-out;
}
.ielts-review .answer-choice:hover { background: var(--if-muted); }
.ielts-review .correct-answer { background: #F3FFEE; border-color: var(--if-success); }
.ielts-review .user-answer    { border-color: var(--if-danger); }
.ielts-review .explanation-card { border-left: 4px solid var(--if-gold-bright); padding-left: 1rem; }
.ielts-review .answer-label { font-weight: 600; margin-right: .5rem; }

@media (max-width: 640px) {
  .ielts-review-score { margin-left: 0; width: 100%; text-align: left; }
}


/* =====================================================================
   TESTGLIDER PAGE GRAMMAR -- ported 2026-08-18 (HANDOFF 10.21)
   =====================================================================
   Copied from design/sat-landing-testglider.html, the approved reference
   specimen. The declarations are that file's, unchanged. Two adaptations:

     1. EVERY SELECTOR IS SCOPED UNDER .ielts-page. The reference is a
        standalone page and can use bare .utils / .tcard. This stylesheet
        loads through layouts/app.blade.php, which TOEFL and the homepage
        also use, so an unscoped .tests rule here would restyle them --
        the exact mistake the header of this file exists to prevent.
     2. Its TestGlider var names map onto this file's --if-* tokens wherever
        the value is identical: --whiteBlue == --if-bg, --lightGray ==
        --if-border, --black == --if-fg, --darkGray == --if-muted-fg,
        --almostBlack == --if-navy-soft, --r == --if-r, --r-xl == --if-r-lg.
        The rest were added to the token block above.
   ===================================================================== */

/* ---- utility cards: bg #f7f9fb, radius 16, pad 24, 248px tall ---- */
/* margin-top is 0, not Reference A's 32px. A and B differ here: the SAT
   specimen leaves 32px under the sub-nav, TestGlider's live IELTS listing
   leaves 1px and drops straight into the cards. Reference B is authoritative
   on structure for this page, so B wins. */
/* margin-bottom replaces the separation the four-paper row used to provide.
   With that row gone the rail heading sat flush against the cards at 0px;
   Reference B leaves ~48px between the utility block and "Closer to your goal". */
.ielts-page .utils{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-top:0;margin-bottom:48px;}
.ielts-page .util{
  position:relative;overflow:hidden;min-height:248px;
  background:var(--if-bg);border-radius:var(--if-r);padding:24px;
  display:block;color:inherit;text-decoration:none;
  transition:transform var(--if-t-med) var(--if-ease),box-shadow var(--if-t-med) var(--if-ease);
}
.ielts-page .util:hover{transform:translateY(-3px);box-shadow:0 12px 28px -14px var(--if-black-12);}
.ielts-page .util .kicker{font-size:14px;color:var(--if-muted-fg);margin:0 0 4px;}
.ielts-page .util .title{font-size:26px;font-weight:700;color:var(--if-fg);letter-spacing:-.02em;margin:0;}
.ielts-page .util .art{position:absolute;right:20px;bottom:18px;width:120px;height:120px;opacity:.95;}
.ielts-page .util .art svg{width:100%;height:100%;display:block;}
.ielts-page .util:nth-child(2){background:var(--if-blue-50);}
.ielts-page .util:nth-child(3){background:#F2FDFF;}
.ielts-page .util[aria-disabled="true"]{opacity:.7;pointer-events:none;}
.ielts-page .util:focus-visible{outline:3px solid var(--if-gold);outline-offset:2px;}

/* ---- "Closer to your goal" rail ---- */
.ielts-page .rail-wrap{position:relative;}
.ielts-page .rail{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(340px,1fr);
  gap:28px;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;   /* their rail shows no scrollbar */
}
.ielts-page .rail::-webkit-scrollbar{display:none;}
.ielts-page .rail-card{
  scroll-snap-align:start;border-radius:var(--if-r);padding:24px;min-height:190px;
  display:flex;flex-direction:column;justify-content:space-between;
  color:var(--if-fg);text-decoration:none;
  transition:transform var(--if-t-med) var(--if-ease);
}
.ielts-page .rail-card:hover{transform:translateY(-3px);}
.ielts-page .rail-card .nm{font-size:20px;font-weight:700;letter-spacing:-.01em;}
.ielts-page .rail-card .sub{font-size:13px;color:var(--if-navy-soft);opacity:.75;}
.ielts-page .rail-card:focus-visible{outline:3px solid var(--if-gold);outline-offset:2px;}
/* The two rail controls are one rule. .rail-prev was added 2026-08-19 -- the
   rail scrolled both ways from the first day but only offered a control one
   way, so a mouse user who scrolled right had no way back short of a trackpad
   swipe. Everything except the side is shared, so they cannot drift apart. */
.ielts-page .rail-prev,
.ielts-page .rail-next{
  position:absolute;top:50%;transform:translateY(-50%);
  width:34px;height:34px;border-radius:50%;background:var(--if-card);
  border:1px solid var(--if-border);display:grid;place-items:center;cursor:pointer;
  color:var(--if-navy-soft);box-shadow:0 2px 8px var(--if-black-08);
  transition:background-color var(--if-t-fast) ease;
}
.ielts-page .rail-prev{left:-14px;}
.ielts-page .rail-next{right:-14px;}
.ielts-page .rail-prev:hover,
.ielts-page .rail-next:hover{background:var(--if-bg);}
.ielts-page .rail-prev svg,
.ielts-page .rail-next svg{width:16px;height:16px;}

/* ---- 3-up grid of square tinted test cards ---- */
.ielts-page .tests{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px;}
.ielts-page .tcard{
  position:relative;overflow:hidden;aspect-ratio:1/1;padding:24px;
  border-radius:var(--if-r-lg);display:flex;flex-direction:column;
  color:var(--if-card-ink);text-decoration:none;
  transition:transform var(--if-t-med) var(--if-ease),box-shadow var(--if-t-med) var(--if-ease);
}
.ielts-page .tcard:hover{transform:translateY(-4px);box-shadow:0 18px 36px -18px var(--if-black-12);}
.ielts-page .tcard[aria-disabled="true"]{opacity:.78;pointer-events:none;}
.ielts-page .tcard:focus-visible{outline:3px solid var(--if-fg);outline-offset:3px;}
.ielts-page .tcard .nm{
  font-size:26px;font-weight:700;color:var(--if-card-ink);
  line-height:40px;letter-spacing:-.26px;margin:0;
}
.ielts-page .graded{
  display:inline-flex;align-items:center;gap:4px;align-self:flex-start;
  background:var(--if-card);border-radius:var(--if-r-sm);
  padding:2px 8px 2px 4px;font-size:12px;font-weight:500;color:var(--if-muted-fg);
  margin-top:10px;
}
.ielts-page .graded svg{width:14px;height:14px;color:var(--if-card-ink);}
/* The reference holds an inline constellation SVG in this slot. IELTS ships
   real 1408x768 cityscape photography, so the same slot holds the badge
   image, cropped to the card and rounded.

   IN FLOW, not absolute -- changed 2026-08-19, and the size is deliberately
   untouched at 150x96.

   The reference positions this slot `absolute; bottom:96px`, and that is fine
   for what IT holds: a transparent constellation whose strokes reading through
   the translucent stat panel looks intentional. A PHOTOGRAPH in the same slot
   does not read that way -- it reads as a collision, which is what the city
   badge was doing. Measured on the deployed card: the badge's bottom edge sat
   21px INSIDE the stat panel.

   A bigger `bottom` would only move the collision, because .stat is
   content-sized (its second line, the paper list, wraps at some widths) while
   an absolute offset is a constant. As an ordinary flex item it cannot collide
   at all: .stat keeps `margin-top:auto`, so all the free space in the card
   lands between the badge and the panel and the badge is pushed up by exactly
   as much as the panel grows. Measured: 9px clear with today's two-line panel,
   and still 0px -- touching, never overlapping -- with a forced three-line one.

   flex:0 0 auto is what holds the size: the badge gives up none of its 96px
   when the card runs short of room. */
.ielts-page .tcard .sky{
  align-self:flex-end;
  flex:0 0 auto;
  margin-top:10px;
  width:150px;height:96px;
  border-radius:var(--if-r-sm);overflow:hidden;pointer-events:none;
  box-shadow:0 8px 20px -10px var(--if-black-12);
}
.ielts-page .tcard .sky img{width:100%;height:100%;object-fit:cover;display:block;}
.ielts-page .stat{
  margin-top:auto;background:var(--if-white-60);border-radius:var(--if-r-stat);padding:16px;
  display:grid;gap:6px;font-size:16px;
}
.ielts-page .stat div{display:flex;align-items:center;gap:8px;color:var(--if-card-ink);font-size:14px;}
.ielts-page .stat svg{width:16px;height:16px;flex:0 0 auto;color:var(--if-navy-soft);}

@media (prefers-reduced-motion: reduce){
  .ielts-page .util,.ielts-page .rail-card,.ielts-page .tcard{transition:none;}
  .ielts-page .util:hover,.ielts-page .rail-card:hover,.ielts-page .tcard:hover{transform:none;}
}
@media (max-width:1080px){
  .ielts-page .utils{grid-template-columns:1fr;}
  .ielts-page .tests{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:760px){
  .ielts-page .tests{grid-template-columns:1fr;}
  .ielts-page .rail{grid-auto-columns:minmax(280px,1fr);}
  /* `bottom`/`right` dropped 2026-08-19 with the switch to flow layout -- they
     were inert once .sky stopped being absolutely positioned. The narrower
     badge here is the pre-existing responsive size and is left alone. */
  .ielts-page .tcard .sky{width:120px;height:78px;}
}

/* ==========================================================================
   "Leave the test?" — the exit confirmation. §10.31, 2026-08-31.

   Prefixed ielts- like every other rule added since §10.24: layouts/ielts is
   IELTS's own, but ielts.css is loaded alongside exam.css (which TOEFL shares),
   so an unprefixed .dialog rule here would reach TOEFL's exam screens.

   .dialog / .dialog-overlay come from exam.css and are reused for the backdrop
   and the show/hide mechanism, exactly as _modal-resume-or-start does. Only the
   INSIDE of the dialog is styled here.
   ========================================================================== */
/* exam.css paints .dialog-overlay an opaque whitesmoke, which is right for the
   full-screen resume prompt but wrong for a confirmation that should read as
   sitting ON TOP of the paper. Dimmed instead, IELTS-scoped so the resume
   modal and TOEFL keep the ground they have. */
.ielts-leave-dialog { background-color: rgba(17, 17, 20, .55); }
.ielts-leave-dialog .dialog-content { padding: 1rem; }

.ielts-leave-content {
  display: block;
  max-width: 42rem;
  width: calc(100vw - 2rem);
  padding: 2rem;
  border-radius: 1rem;
  background: #FFFFFF;
  text-align: left;
}

/* The title carries a highlighter swipe behind it rather than a colour change,
   which is how TestGlider draws attention here. Drawn with a gradient on the
   background so it sits behind the descenders like a real marker would. */
.ielts-leave-title {
  margin: 0 0 1rem;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: #111114;
  display: inline;
  background-image: linear-gradient(transparent 55%, #FFD34E 55%);
  background-repeat: no-repeat;
  padding: 0 .25rem .1rem 0;
}

.ielts-leave-copy {
  margin: 1.25rem 0 0;
  font-size: .9375rem;
  line-height: 1.6;
  color: #4A4B4D;
}
.ielts-leave-copy b { color: #111114; font-weight: 700; }

.ielts-leave-table {
  width: 100%;
  margin-top: 1.25rem;
  border-collapse: collapse;
  font-size: .875rem;
}
.ielts-leave-table th {
  text-align: left;
  font-weight: 400;
  color: #4A4B4D;
  padding: 0 .75rem .5rem 0;
  border-bottom: 1px solid #111114;
}
.ielts-leave-table td {
  padding: .5rem .75rem .5rem 0;
  color: #111114;
}
/* Zebra striping on the FIRST column pair only would look lopsided on the split
   table, so the row is striped whole. */
.ielts-leave-table tbody tr:nth-child(odd) { background: #F7F9FB; }

.ielts-leave-table--split th:nth-child(3),
.ielts-leave-table--split td:nth-child(3) { padding-left: 1.5rem; }
/* An odd number of checkpoints leaves the last right-hand cell empty; it must
   not draw a stripe edge that looks like a missing row. */
.ielts-leave-table--split td:empty { background: transparent; }

.ielts-leave-actions {
  display: flex;
  justify-content: flex-end;
  gap: .75rem;
  margin-top: 1.75rem;
}
.ielts-leave-btn {
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  padding: .7rem 1.4rem;
  border-radius: .5rem;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.ielts-leave-btn--ghost {
  background: #FFFFFF;
  border-color: #D6D8DC;
  color: #36373B;
}
.ielts-leave-btn--ghost:hover { background: #F7F9FB; }
.ielts-leave-btn--go {
  background: #FFD34E;
  color: #111114;
}
.ielts-leave-btn--go:hover { background: #F5C32C; color: #111114; }
.ielts-leave-btn:focus-visible { outline: 3px solid #175FFC; outline-offset: 2px; }

@media (max-width: 640px) {
  .ielts-leave-content { padding: 1.25rem; }
  /* The split table cannot hold four columns on a phone; it becomes two. */
  .ielts-leave-table--split th:nth-child(3), .ielts-leave-table--split th:nth-child(4),
  .ielts-leave-table--split td:nth-child(3), .ielts-leave-table--split td:nth-child(4) {
    display: none;
  }
  .ielts-leave-actions { flex-direction: column-reverse; }
  .ielts-leave-btn { justify-content: center; }
}

/* ---- Sound Test, the Listening pre-check. §10.31 ---- */
.ielts-sound-title {
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: #111114;
  margin: 0 0 1.5rem;
  text-align: center;
}
.ielts-sound-art { display: block; width: 20rem; max-width: 100%; margin-bottom: 1.5rem; }
.ielts-sound-art svg { width: 100%; height: auto; display: block; }

.ielts-sound-play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  min-width: 16rem;
  padding: .9rem 1.5rem;
  border: 0;
  border-radius: .625rem;
  background: #E11F3E;
  color: #FFFFFF;
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
}
.ielts-sound-play:hover { background: #C4102D; }
.ielts-sound-play:focus-visible { outline: 3px solid #175FFC; outline-offset: 2px; }
.ielts-sound-play svg { width: 1.15rem; height: 1.15rem; flex: 0 0 auto; }

.ielts-sound-steps {
  margin: 1.75rem 0 0;
  padding-left: 1.25rem;
  font-size: .9375rem;
  line-height: 1.75;
  color: #4A4B4D;
  text-align: left;
}
.ielts-sound-steps li { margin-bottom: .5rem; }
.ielts-sound-steps b { color: #111114; font-weight: 700; }

/* ---- the Speaking listen-back gate's countdown. §10.31 ---- */
.ielts-listen-back {
  margin: .6rem 0 0;
  font-size: .8125rem;
  line-height: 1.4;
  color: #8A6D00;
  background: #FFF8E1;
  border-left: 3px solid #FFD34E;
  padding: .45rem .7rem;
  border-radius: 0 .35rem .35rem 0;
  max-width: 18rem;
}
.ielts-listen-back b { color: #6B5400; font-weight: 700; }

/* ==========================================================================
   Highlights and notes. §10.31.

   The highlight colour is the same #FDF1A8 the DOM-only highlighter used, so
   nothing a candidate is used to seeing changes; what changes is that it
   survives a reload now, and can carry text.
   ========================================================================== */
.ielts-hl {
  background: #FDF1A8;
  cursor: pointer;
  border-radius: 2px;
}
/* A highlight that carries a written note is distinguishable from a plain one
   without opening the panel — otherwise the two are the same yellow and the
   candidate has to click each to find out which is which. */
.ielts-hl--noted {
  background: #FFE07A;
  box-shadow: inset 0 -2px 0 #E8A400;
}

/* ---- the selection toolbar ---- */
.ielts-note-toolbar {
  position: absolute;
  z-index: 40;
  display: none;
  gap: .25rem;
  padding: .25rem;
  background: #FFFFFF;
  border: 1px solid #E8EAED;
  border-radius: .5rem;
  box-shadow: 0 8px 24px -12px rgba(0, 0, 0, .35);
}
.ielts-note-toolbar.is-open { display: flex; }
.ielts-note-tool {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: .15rem;
  border: 0;
  background: transparent;
  padding: .4rem .7rem;
  border-radius: .35rem;
  font-size: .75rem;
  font-weight: 600;
  color: #36373B;
  cursor: pointer;
}
.ielts-note-tool:hover { background: #F7F9FB; color: #175FFC; }
.ielts-note-tool svg { width: 1.1rem; height: 1.1rem; }

/* ---- the docked panel ----
   Fixed to the right edge and translated out of view rather than hidden, so
   opening it animates instead of jumping. It overlays rather than reflowing the
   exam: the passage and question panes are already a measured two-column
   layout, and reflowing them mid-paper would move the text a candidate is
   reading. That is a deliberate divergence from TestGlider, which reflows. */
.ielts-notes-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 22rem;
  max-width: 90vw;
  background: #F1F2F4;
  border-left: 1px solid #E8EAED;
  transform: translateX(100%);
  transition: transform 220ms cubic-bezier(.22, .61, .36, 1);
  z-index: 30;
  display: flex;
  flex-direction: column;
}
.ielts-notes-panel.is-open { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) { .ielts-notes-panel { transition: none; } }

.ielts-notes-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1rem;
  min-height: 3.5rem;
  background: #36373B;
  color: #FFFFFF;
  font-weight: 700;
}
.ielts-notes-close {
  border: 0;
  background: transparent;
  color: #FFFFFF;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: .25rem .5rem;
}
.ielts-notes-body { padding: 1rem; overflow-y: auto; flex: 1 1 auto; }

.ielts-notes-empty { text-align: center; margin-top: 40%; }
.ielts-notes-empty-title { margin: 0 0 .35rem; font-size: 1rem; font-weight: 700; color: #36373B; }
.ielts-notes-empty-sub { margin: 0; font-size: .8125rem; color: #8A8C91; }

.ielts-note-card {
  background: #FFFFFF;
  border-radius: .5rem;
  padding: .875rem;
  margin-bottom: .75rem;
  border: 1px solid #E8EAED;
}
.ielts-note-card.is-active { border-color: #175FFC; box-shadow: 0 0 0 3px rgba(23, 95, 252, .15); }
.ielts-note-quote {
  margin: 0 0 .5rem;
  font-size: .8125rem;
  line-height: 1.5;
  color: #4A4B4D;
}
.ielts-note-quote b { color: #111114; }
.ielts-note-text {
  width: 100%;
  min-height: 4.5rem;
  resize: vertical;
  border: 1px solid #E8EAED;
  border-radius: .35rem;
  background: #F7F9FB;
  padding: .5rem;
  font: inherit;
  font-size: .875rem;
  color: #111114;
}
.ielts-note-text:focus { outline: 2px solid #175FFC; outline-offset: -1px; background: #FFFFFF; }
.ielts-note-actions { display: flex; justify-content: flex-end; margin-top: .5rem; }
.ielts-note-delete {
  border: 0;
  background: transparent;
  color: #B4232A;
  font-size: .8125rem;
  font-weight: 700;
  cursor: pointer;
  padding: .25rem .35rem;
}
.ielts-note-delete:hover { text-decoration: underline; }

/* The Notes button in the exam navbar. */
.ielts-notes-toggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}

/* ==========================================================================
   "Would you like to resume?" — the start/continue prompt. §10.32.

   Rebuilt to match TestGlider, confirmed by direct comparison in their product:
   compact, MONOCHROME, and rendered OVER the page the candidate was already
   looking at rather than on a blank screen of its own. The old version was a
   plain white card on an opaque whitesmoke ground with a green button and a
   blue one — three palettes that appear nowhere else in IELTS, on a page with
   nothing else on it.

   The dim scrim is the substantive half of "over the page": the exam cards stay
   visible behind it, so the prompt reads as a question about the thing you just
   clicked instead of a page you were sent to.
   ========================================================================== */
.ielts-resume-dialog {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(17, 17, 20, .55);
}
.ielts-resume-dialog.show,
.ielts-resume-dialog.is-open { display: flex; }

.ielts-resume-card {
  width: 100%;
  max-width: 30rem;
  background: #FFFFFF;
  border-radius: 1rem;
  padding: 2rem;
  text-align: center;
  box-shadow: 0 24px 64px -24px rgba(0, 0, 0, .45);
}
.ielts-resume-title {
  margin: 0 0 .75rem;
  font-size: 1.375rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: #111114;
}
.ielts-resume-copy {
  margin: 0 0 1.75rem;
  font-size: .9375rem;
  line-height: 1.6;
  color: #4A4B4D;
}

.ielts-resume-actions {
  display: flex;
  gap: .75rem;
  justify-content: center;
}
.ielts-resume-btn {
  flex: 1 1 0;
  max-width: 12rem;
  border: 0;
  cursor: pointer;
  padding: .85rem 1rem;
  border-radius: .5rem;
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Light grey for the destructive-ish option, solid black for the one the
   candidate almost always wants — TestGlider's own weighting, and the opposite
   of the old green/blue pair which gave "Start New" the louder colour. */
.ielts-resume-btn--new {
  background: #F0F1F3;
  color: #4A4B4D;
}
.ielts-resume-btn--new:hover { background: #E4E6E9; color: #111114; }
.ielts-resume-btn--resume {
  background: #111114;
  color: #FFFFFF;
}
.ielts-resume-btn--resume:hover { background: #000000; color: #FFFFFF; }
.ielts-resume-btn:focus-visible { outline: 3px solid #175FFC; outline-offset: 2px; }

@media (max-width: 480px) {
  .ielts-resume-card { padding: 1.5rem; }
  .ielts-resume-actions { flex-direction: column; }
  .ielts-resume-btn { max-width: none; }
}

/* ==========================================================================
   Listening part header: the progress bar sitting across the status line.
   §10.33.

   THE CAUSE. exam.css:213 styles .recording-body as a grid with three fixed
   tracks:

       .recording-body { display: grid; grid-template-rows: 50px max-content max-content; }

   That is correct for the markup it was written for — an empty spacer <div>
   filling the 50px track, then .recording-img-frame, then the controls. IELTS's
   listening/play-content.blade.php and writing/play-content.blade.php still have
   exactly that shape, and they must keep it.

   The listening PART header does not. It puts the whole block — part label,
   <audio>, play button, progress <meter>, the "plays once only" status line and
   the check-answers timer — inside ONE centred child. A single grid item lands
   in track 1, which is pinned to 50px, so roughly 150px of content overflowed a
   50px row and painted over the lines beneath it. That is why the grey meter
   appeared to sit across the text: nothing was mispositioned, the row was simply
   too short for what was in it.

   THE FIX is to stop imposing a three-track grid on a one-child container.
   Not a z-index bump — that would hide the status line behind the bar rather
   than give it room. Not extra padding on the header — the header's height was
   never the problem, one track's was.

   SCOPE. .recording-body lives in exam.css, which TOEFL loads through
   layouts/exam.blade.php, and TOEFL's own listening, speaking and writing
   play-content views all use the class. CLAUDE.md rule 4 keeps exam.css
   untouched, so this is an IELTS override, and it is narrowed to
   [data-listening-part] so IELTS's other two .recording-body screens keep the
   grid they still need.
   ========================================================================== */
.ielts-exam [data-listening-part] > .recording-body {
  display: block;
}
