/* El-Amin97 member navigation — stylesheet half of the nav shim.
 *
 * The mirrored pages already contain GoDaddy's full membership menu: both
 * states, as siblings. Measured on the served page, their own bundle runs and
 * expresses the state with INLINE display styles, for a signed-out visitor:
 *
 *     .membership-icon-logged-out    display:block   <- the header control
 *     .membership-icon-logged-in     display:none
 *     .membership-links-logged-out   display:block   <- mobile nav
 *     .membership-links-logged-in    display:none
 *     .membership-header-logged-in   display:none
 *
 * So the menu machinery is intact; the only thing wrong is the identity behind
 * it, which is the placeholder captured from the live site
 * ("filler@godaddy.com"). nav.js supplies the real identity from OUR auth
 * service, and the rules below flip the state.
 *
 * Their state lives in inline styles, so ours must outrank inline => !important.
 * It is scoped to a class on <html>, so nothing changes until nav.js has an
 * answer, and the login/admin pages (which never get that class) are unaffected.
 *
 * DELIBERATELY NOT TOUCHED: .membership-sign-in / .membership-sign-out. Despite
 * the names these are the two DROPDOWN CONTAINERS, not the two states: the
 * signed-out dropdown carries membership-sign-out and the signed-in one carries
 * membership-sign-in. They are display:none because they are CLOSED, and the
 * site's dropdown JS opens them on click. Styling them here would break the menu.
 */

html.elamin-signed-out :is(.membership-icon-logged-in,
                           .membership-links-logged-in,
                           .membership-header-logged-in) { display: none !important; }

html.elamin-signed-out :is(.membership-icon-logged-out,
                           .membership-links-logged-out) { display: block !important; }

html.elamin-signed-in :is(.membership-icon-logged-in,
                          .membership-links-logged-in,
                          .membership-header-logged-in) { display: block !important; }

html.elamin-signed-in :is(.membership-icon-logged-out,
                          .membership-links-logged-out) { display: none !important; }

/* "Sign out" is a <p> on the live site; nav.js makes it clickable. Give it the
   affordance the rest of the menu links have. */
html.elamin-signed-in [id$="-membership-sign-out"] { cursor: pointer; }

/* ---- site search ---------------------------------------------------------
 * Styles for the search control that nav.js injects into the header, and for
 * the results list on /search.
 *
 * These live in nav.css — NOT in the auth service's own inline stylesheet —
 * because the mirrored pages load nav.css and never see the service's CSS. The
 * first version of this feature put the rules in the service's sheet, so on a
 * mirrored page the `.sr` screen-reader rule never applied and the "Search the
 * site" label rendered as visible text next to the box. The control is injected
 * into MIRRORED pages, so its styles must ship with the shim.
 *
 * Colours are the measured site tokens (accent #0075c1, body font Gudea) written
 * out literally: nav.css has no :root block of its own to inherit from.
 */
.head-search{flex:0 0 auto;display:flex;align-items:center;margin-right:12px}
.head-search form{display:flex;align-items:stretch;margin:0}
.head-search input[type=search]{width:170px;padding:6px 9px;font:14px Gudea,Georgia,serif;
  border:1px solid #d9d9d9;border-right:0;background:#fcfcfc;color:#2b2b2b;border-radius:0}
.head-search input[type=search]:focus{outline:2px solid #0075c1;outline-offset:-1px;background:#fff}
.head-search button{margin:0;width:auto;padding:6px 10px;cursor:pointer;border:0;
  background:#0075c1;color:#fff;display:inline-flex;align-items:center;gap:6px;
  font-family:Gudea,Georgia,serif}
.head-search button:hover{background:#0068ad}
.head-search button svg{width:14px;height:14px;display:block}

/* Visually hidden but available to screen readers. Needed because the input has
   a placeholder, not a visible label. */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ---- search results (the /search page) ---- */
.hits{list-style:none;margin:4px 0 26px;padding:0}
.hits .hit{padding:16px 0;border-bottom:1px solid #d9d9d9}
.hits .hit:last-child{border-bottom:0}
.hit-t{font-family:'Old Standard TT',serif;font-size:20px;color:#0075c1;text-decoration:none}
.hit-t:hover{text-decoration:underline}
.hit-p{font-size:12px;color:#5f5f5f;margin:3px 0 6px;word-break:break-all}
.hit-s{margin:0;font-size:14px;color:#2b2b2b;line-height:1.55}
.hit-s mark{background:#fff3b0;color:inherit;padding:0 1px}
/* The kind badge ("Page" / "Document") is appended straight after the title
 * anchor — `.hit-t</a><span class="pill">` — so with no left margin it butted
 * flush against the last glyph and read as part of the title. The base `.pill`
 * rule lives in the SERVICE's inline sheet and carries no margin, so it is
 * overridden here where it is needed instead of globally: the admin `.top`
 * pills sit in a flex row that already supplies `gap:14px`, and a global
 * margin-left would double-space those. */
.hits .hit .pill{margin-left:8px}
.pill.locked{background:#f4f4f4;border-color:#d9d9d9;color:#5f5f5f}

/* ---- the /search page layout --------------------------------------------
 * Three things change on this page, and only on this page, via the
 * `search-page` class the service puts on <html> (see page(html_class=...)):
 *
 *   1. The header control is hidden. On /search the hero below is the ONLY
 *      search box, so leaving the header one visible would offer two inputs
 *      competing for the same query.
 *   2. The column widens. The default .wrap is 620px — sized for a sign-in
 *      form — which cramps a result listing that carries a title, path badge
 *      and two-line snippet. `wide` takes it to 880px.
 *   3. The snippet keeps a readable measure (~72ch) inside the wider card, so
 *      widening the container does not stretch body text into unreadable
 *      lines. The container expands; the field stays constrained.
 *
 * The hero form lives OUTSIDE .card — it sits above it, centred — and is gone
 * from the bottom of the results, where it used to duplicate the header box.
 */
html.search-page .head-search{display:none}
main.wrap.wide{max-width:880px}
.search-page .hits .hit-s{max-width:72ch}

.search-hero{display:flex;align-items:stretch;gap:0;margin:0 0 22px;
  justify-content:center;max-width:560px;margin-left:auto;margin-right:auto}
.search-hero input[type=search]{flex:1 1 auto;min-width:0;padding:12px 14px;
  font:15px Gudea,Georgia,serif;border:1px solid #d9d9d9;border-right:0;
  background:#fff;color:#2b2b2b;border-radius:0}
.search-hero input[type=search]:focus{outline:2px solid #0075c1;outline-offset:-1px}
.search-hero button{margin:0;width:auto;padding:12px 22px;cursor:pointer;border:0;
  background:#0075c1;color:#fff;font:700 13px Gudea,Georgia,serif;
  text-transform:uppercase;letter-spacing:.819px}
.search-hero button:hover{background:#0068ad}

/* ---- pager (bottom of the /search card) ----------------------------------
 * The hero form above the card is a GET to /search with only `q`, so submitting
 * a new search intentionally drops `page` and returns to page 1 — the pager is
 * the only thing that carries the page number.
 *
 * The pager stays INSIDE the (now wider) results card, aligned left under the
 * listing, because it belongs to the listing rather than to the page. Disabled
 * Prev/Next are <span>, not a dead <a>, so they are not focusable and screen
 * readers do not announce a link that does nothing.
 */
.pager{display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  margin:22px 0 2px;padding-top:18px;border-top:1px solid #d9d9d9}
.pager .pg{display:inline-block;min-width:34px;padding:7px 10px;text-align:center;
  font:14px Gudea,Georgia,serif;color:#0075c1;text-decoration:none;
  border:1px solid #d9d9d9;background:#fff}
.pager a.pg:hover{background:#0075c1;border-color:#0075c1;color:#fff}
.pager .pg.cur{background:#0075c1;border-color:#0075c1;color:#fff;font-weight:700}
.pager .pg.off{color:#b4b4b4;background:#fafafa;border-color:#e6e6e6}
.pager .pg.gap{border:0;background:transparent;color:#5f5f5f;min-width:18px}
.pager a.pg:focus-visible{outline:2px solid #0075c1;outline-offset:2px}

/* ---- mobile: the /search page and the injected control ------------------- *
 * MEASURED at 390x844, /search?q=the, before these rules:
 *   hero 346 wide (input 251 + 95 button) — a single row, fine
 *   card 346 wide but hits only 276, and 246 at 360px, because .card kept its
 *   desktop 34px side padding and the page kept .wrap's 22px
 *   h1 34px, .hit-t 20px — sized for a 880px desktop column
 *   pager 6 items on ONE 276px row (93px tall at 390, wrapping badly)
 *
 * So: give the results back the horizontal space (.card padding and .wrap
 * gutter both shrink), scale the type down, let the pager wrap deliberately,
 * and stack the hero only where a phone really cannot fit input+button.
 *
 * The hero stacks at <=400px rather than at the usual 480: at 390 it still fits
 * on one row with a usable ~250px input, and a stacked form would consume more
 * vertical space than it buys. It stacks only when the input would fall below
 * ~200px (360 - 28 gutter - 36 padding - 95 button = 201).
 */
@media (max-width:760px){
  html.search-page .head-search{display:none}
  main.wrap.wide{max-width:100%}
  .search-hero{max-width:none;margin:0 0 16px}
  .search-page .hits .hit-s{max-width:none}
  .hits .hit{padding:13px 0}
  .hit-t{font-size:17px;line-height:1.3}
  .hit-p{font-size:11px}
  .hit-s{font-size:14px}
  /* Deliberate wrap, centred, so 6 chips break into two tidy rows instead of
     one cramped row that overflows its card. */
  .pager{justify-content:center;gap:5px;margin:18px 0 0}
  .pager .pg{min-width:30px;padding:6px 8px;font-size:13px}
}
@media (max-width:400px){
  /* Below ~400px the input would be under 200px wide beside the button, so
     stack them: full-width input, full-width button under it. */
  .search-hero{flex-direction:column;gap:8px}
  .search-hero input[type=search]{width:100%;border-right:1px solid #d9d9d9}
  .search-hero button{width:100%;padding:12px 14px}
  .hit-t{font-size:16px}
  .pager .pg{min-width:28px;padding:5px 7px;font-size:12px}
}

/* The control nav.js injects into mirrored pages: at <=760 it must not crowd
   the site's own utilities row, so it shrinks rather than pushing the row over.
   Measured at 390 on the mirrored home: 204x32 at x=126 — it fits, but 204px is
   half the viewport, so it is narrowed and the button collapsed to the icon.

   The width is FLUID, not a fixed 120/96. A fixed width wastes the space the
   header has spare: measured at 390, the brand column reserves 262px while the
   brand mark itself paints only 96px, so the control sat in a hard 96px box
   with ~110px of dead space beside it. Sizing it off the viewport instead lets
   it take that slack and stop short of the hamburger.

   The 232px subtracted is the space the header genuinely needs, measured at
   every phone width: 8px row padding + 80px brand mark + ~50px clearance from
   it + 40px hamburger + 8px right margin + 30px collapsed button. Subtracting
   it holds the control's right edge a constant 8px left of the hamburger and
   ~50px clear of the brand mark at 360/390/414/480, with no horizontal
   overflow at any width (verified 320-1280).

   The clamp floor is 96px — exactly the value this rule used to hard-code below
   480px — so no width gets narrower than before; 320px views are unchanged.
   Capped at 240px so a small tablet does not get an absurdly long field. Above
   the 760px breakpoint the original 170px desktop width is untouched. */
@media (max-width:760px){
  .head-search{margin-right:8px}
  .head-search input[type=search]{
    width:clamp(96px, calc(100vw - 232px), 240px);padding:5px 7px;font-size:13px}
  .head-search button{padding:5px 8px}
}
/* No separate <=480 rule: the clamp floor already bottoms out at 96px, which is
   what the old @media (max-width:480px){width:96px} rule set. Keeping both would
   re-pin the width at exactly the small widths the clamp exists to un-pin. */

/* ---- read aloud ---------------------------------------------------------- *
   The "Listen" control beside every document link, and the page-level control
   in the header. Both live HERE rather than in the service's inline sheet,
   because this is the only stylesheet the MIRRORED pages load — a rule written
   only into authsvc.py's CSS block is invisible on the site itself, which is
   exactly how the "Search the site" label once ended up rendering as visible
   text on mirrored pages. One source, both surfaces.

   The button is deliberately inline and small: it sits beside download links in
   lists the site's own CSS already lays out, so it must not disturb their
   flow. `inline-flex` keeps the icon and the word on one line, and
   `vertical-align:middle` stops it from sitting on the text baseline, which
   reads as misaligned next to a 16px link. */
/* Sized down after overshooting. The history ran 12px -> 15px -> 17px, each
   step fixing a real problem (unreadable beside the site's 16px links, then
   fine print next to the download link), but 17px with a 22px icon and 9/20
   padding made the pill as heavy as the download link it sits beside -- it
   started competing with the primary action instead of annotating it.
   Settled at 14px with a 19px icon: still clearly larger than the 12px it
   started at, still legible, but no longer the loudest thing in the row.
   The border and pill radius scale with it so it does not read as a stretched
   small control. */
.listen-wrap{display:inline-block;margin-left:10px;vertical-align:middle;white-space:nowrap}
/* ---- form-control reset for the injected buttons -------------------------
 * The Listen controls changed from <a> to <button> in the in-page-reader
 * redesign, and a <button> does NOT inherit the page's typography the way an
 * anchor does: the user-agent stylesheet applies `font: 13.333px Arial`,
 * `border: 2px outset`, `padding: 1px 6px` and `appearance: auto`.
 *
 * Measured on /el-amin97s-home.html, that is what made these buttons look
 * "changed from what we worked out":
 *   - the pill rendered in Arial at 94px wide where the identical <a> was 90px
 *     in Gudea (the site's own font), because the label's typeface came from the
 *     button, not from the page;
 *   - the page speaker was a 34px disc with a 2px OUTSET BLACK RING drawn over
 *     the blue, and border-box meant that ring ate into the 34px -- the 22px
 *     icon was squeezed to 18px WIDE while staying 22px tall, so the speaker
 *     glyph was visibly squashed as well as ringed.
 *
 * `font-family:inherit` restores the anchor's typographic inheritance and
 * `appearance:none` removes the native widget rendering. These are declared
 * BEFORE the per-control rules below so any explicit value there still wins. */
.listen-btn,.listen-page-btn{
  font-family:inherit;-webkit-appearance:none;appearance:none;box-sizing:border-box;
}
.listen-btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:5px 13px;border:1.5px solid var(--blue,#0075c1);border-radius:16px;
  color:var(--blue,#0075c1);background:#fff;
  font-size:14px;line-height:1.3;font-weight:600;text-decoration:none;cursor:pointer;
}
.listen-btn:hover,.listen-btn:focus{background:var(--blue,#0075c1);color:#fff;text-decoration:none}
.listen-btn svg{width:19px;height:19px;flex:0 0 auto}
/* The page-level control is icon-only: it sits in the utilities row beside the
   search box and the account icon. Sized up from 32px because at 32 it read as
   a decorative glyph rather than a control; the filled tint is what carries the
   "this is a button" signal at header scale, and that survives at any size.
   Then sized back DOWN from 56 to 34, because the growth had run away: 32 -> 44
   -> 52 -> 56 over three rounds, each step justified on its own, leaving a 56px
   disc next to a 32px-tall search box and a 30px account icon — the speaker was
   the tallest thing in the row, so every page's header read as if listening
   were the primary action. 34px matches its neighbours (measured: search 32,
   account icon 30) and still clears the 32px tap-target floor. The icon keeps
   a high icon-to-disc ratio (~0.65) so it still reads as a speaker, not as
   decoration inside a disc. */
.listen-page-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;margin-right:10px;border-radius:50%;
  padding:0;border:0;
  color:#fff;background:var(--blue,#0075c1);text-decoration:none;
  box-shadow:0 1px 3px rgba(0,0,0,.18);
}
.listen-page-btn:hover,.listen-page-btn:focus{background:#0068ad;box-shadow:0 2px 6px rgba(0,0,0,.24)}
.listen-page-btn svg{width:22px;height:22px}
/* ---- the in-page reader (Read aloud) ------------------------------------ *
 * Replaces the separate /read/* page. A fixed panel docked at the RIGHT edge,
 * vertically centred ("sticky about the right side, mid page"), which slides
 * out of and into view ("contract/expand") rather than navigating anywhere.
 *
 * WHY fixed AND NOT sticky: `position:sticky` only sticks within its parent's
 * box, so a panel inside the article would stop following once you scrolled
 * past the article — and these pages are 10000px+ tall. `fixed` keeps it
 * available for the whole scroll, which is what "stays sticky" asks for.
 *
 * The collapsed state is a translate of 100% + the tab's own width, so the TAB
 * remains on screen. A panel that slid fully off would have no visible handle
 * and would read as broken. The tab therefore lives OUTSIDE the sliding body.
 *
 * Low-profile by construction: transport row, scrubber, one line of title.
 * The old page carried the document path, a kind badge, a duration line, a
 * disclaimer and back-links; inside the parent page all of that is already on
 * screen, so it is deliberately absent.
 *
 * Sizes are in rem-free px and tuned to sit under the site's own header scale:
 * the panel is ~268px wide, small enough not to cover a phone's content, and
 * the tab is 34px — the same as the header speaker, so the control that opens
 * it and the control inside it are visually the same size.
 *
 * The tab was 44px for a while, which broke that intent: the handle that OPENS
 * the panel was larger than the 34px speaker that summons it, so the reader's
 * own chrome read as the loudest control on the page. Measured now: tab 34,
 * header speaker 34.
 */
.er{position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:2147483000;
  display:flex;align-items:center;font-family:Gudea,Georgia,serif;pointer-events:none;
  /* No layout impact on the page: fixed + zero intrinsic width. */
  max-width:100%}
.er *{pointer-events:auto;box-sizing:border-box}

/* The always-visible handle. */
.er-tab{display:inline-flex;align-items:center;justify-content:center;gap:2px;
  width:auto;height:34px;padding:0 5px 0 7px;margin:0;cursor:pointer;
  border:0;border-radius:8px 0 0 8px;background:var(--blue,#0075c1);color:#fff;
  box-shadow:-2px 1px 6px rgba(0,0,0,.22)}
.er-tab svg{width:19px;height:19px;display:block}
.er-tab:hover,.er-tab:focus{background:#0068ad}
.er-tab-x{font-size:16px;line-height:1;opacity:.85;transition:transform .18s ease}
.er.is-open .er-tab-x{transform:rotate(180deg)}

/* The sliding body. Hidden by translate, not by display:none, so the
   transition is smooth and the audio element keeps playing while collapsed. */
.er-body{width:268px;max-width:76vw;padding:10px 12px 12px;background:#fff;
  border:1px solid #d9d9d9;border-right:0;border-radius:8px 0 0 8px;
  box-shadow:-3px 2px 14px rgba(0,0,0,.16);
  /* closed: pushed out by its own width, leaving the tab showing */
  position:absolute;right:calc(100% - 0px);top:50%;transform:translateY(-50%) translateX(100%);
  transition:transform .22s ease;visibility:hidden}
.er.is-open .er-body{transform:translateY(-50%) translateX(0);visibility:visible}

.er-head{display:flex;align-items:flex-start;gap:6px;margin:0 0 8px}
.er-title{flex:1 1 auto;font-size:13px;font-weight:700;color:#2b2b2b;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical}
.er-close{flex:0 0 auto;width:20px;height:20px;padding:0;margin:0;cursor:pointer;
  border:0;background:transparent;color:#5f5f5f;font-size:17px;line-height:1}
.er-close:hover{color:#2b2b2b}

.er-row{display:flex;align-items:center;gap:8px}
.er-play{flex:0 0 auto;width:34px;height:34px;padding:0;margin:0;cursor:pointer;
  border:0;border-radius:50%;background:var(--blue,#0075c1);color:#fff;
  display:inline-flex;align-items:center;justify-content:center}
.er-play:hover{background:#0068ad}
.er-play[disabled]{background:#c9c9c9;cursor:default}
.er-play svg{width:18px;height:18px;display:block}

/* The scrubber. Native range input, restyled, rather than a custom widget:
   keyboard support (arrows, Home/End), touch and screen readers all come for
   free, and those are exactly the parts a hand-rolled scrubber gets wrong. */
.er-bar{flex:1 1 auto;min-width:0;-webkit-appearance:none;appearance:none;
  height:4px;margin:0;padding:0;border-radius:2px;background:#d9d9d9;cursor:pointer}
.er-bar::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;
  border-radius:50%;background:var(--blue,#0075c1);border:2px solid #fff;
  box-shadow:0 1px 3px rgba(0,0,0,.3)}
.er-bar::-moz-range-thumb{width:12px;height:12px;border-radius:50%;
  background:var(--blue,#0075c1);border:2px solid #fff}
.er-bar:focus-visible{outline:2px solid var(--blue,#0075c1);outline-offset:3px}
.er-bar[disabled]{opacity:.5;cursor:default}

/* Elapsed / total, as "1:23 / 7:59". The elapsed side is fixed-width so the
   numbers do not jitter as the seconds tick, and the pair is grouped so it
   wraps as a unit rather than splitting across lines in the narrow panel. */
.er-time{flex:0 0 auto;font-size:11px;color:#5f5f5f;font-variant-numeric:tabular-nums;
  min-width:30px;text-align:right}
.er-sep,.er-dur{flex:0 0 auto;font-size:11px;color:#8a8a8a;
  font-variant-numeric:tabular-nums}
.er-sep{margin:0 -4px 0 -3px}
.er-dur{min-width:30px;text-align:left;color:#5f5f5f}

.er-note{margin:8px 0 0;font-size:11px;line-height:1.35;color:#5f5f5f}
.er-note:empty{display:none}

/* ---- the passage being spoken -------------------------------------------
 * A <mark> injected around the matched DOM Range, not a class on a container:
 * the passage is normally part of a paragraph, and only a range can highlight
 * part of an element's text.
 *
 * Base state is transparent — every passage is marked up front so the highlight
 * can just move between them, which means the default must not look like 200
 * highlights. Only `.on` is painted.
 *
 * WHY THE PAINTED STATE FORCES ITS OWN COLOURS. The first version set only a
 * background (#ffe680, a pale yellow) and inherited `color` from the passage's
 * own element. Measured on /el-amin97s-home.html, the article's text is NOT one
 * colour: the dominant values are rgb(164,164,164) (26 blocks), rgb(27,27,27)
 * (22), rgb(255,255,255) (12), rgb(94,94,94) (8) and rgb(247,247,247) — a pale
 * grey, a near-black, white and off-white all inside the same body copy, much
 * of it sitting on a coloured section background. Light grey on pale yellow, and
 * white on pale yellow, are both very low contrast — exactly the "generally
 * affecting lighter text colours" that was reported. An inherited colour cannot
 * be fixed by choosing a better background, because no single background is
 * legible behind both white and near-black text.
 *
 * So `.on` declares BOTH `color` (near-black, high contrast on the highlight)
 * and `background`.
 *
 * The base rule KEEPS `color:inherit`, and that is load-bearing rather than
 * tidiness. `<mark>` has a user-agent rule (`background:Mark; color:MarkText`),
 * so a mark with `background:transparent` but no `color` renders its text BLACK
 * — measured: every one of the 44 marked passages reported `rgb(0,0,0)`. That
 * would repaint the whole article the moment the reader loaded, turning white
 * text on the blue sections black. `color:inherit` restores the page's own
 * colour in the unpainted state; `.elamin-say.on` is more specific, so the
 * painted state still wins.
 *
 * The ring is `box-shadow` with a spread rather than a border: a border would
 * change the element's box and reflow the paragraph as the highlight moves. The
 * shadow paints a 3px halo in the same colour as the fill, so a highlight split
 * across a line break (or across inline elements, which is why a Range was used)
 * still reads as one continuous block with no seams.
 *
 * `text-shadow` is cleared inside the highlight: if the passage's own element
 * carries a text-shadow tuned for a dark background, it would smear the now
 * near-black text on the light fill.
 *
 * WHY `box-decoration-break: clone` AND THE DESCENDANT OVERRIDES BELOW.
 * Reported: "the highlighter and text contrast is so small that it makes it
 * challenging to still see the text as it is highlighted". Two separate causes
 * were measured on /el-amin97s-home.html.
 *
 *   [a] A mark that wrapped an H4 followed by a flex DIV — an inline box
 *       containing block children — is FRAGMENTED, so the fill painted only on
 *       thin inline slivers: entry 0 measured 1112x839px on screen and painted
 *       27 yellow pixels, leaving the sentence white-on-blue. The matcher now
 *       rejects oversized ranges (see MAX_MARK_H in nav.js), so this should not
 *       arise; `box-decoration-break: clone` is the belt-and-braces so that a
 *       legitimate multi-line or partially-nested passage paints every
 *       fragment's padding rather than only the first.
 *   [b] Descendants keep their OWN backgrounds. The article carries opaque
 *       section fills (white, #f6f6f6 and a dark #161616 were all measured
 *       inside these pages), and a child with its own background paints OVER
 *       the highlight's fill no matter how opaque that fill is. Forcing the
 *       descendants' background off inside `.on` is what makes the highlight
 *       visible over every section, rather than only over transparent ones.
 *       Only `background-color` is cleared, so an inline chip or badge that
 *       carries a background IMAGE still reads as itself.
 */
.elamin-say{background:transparent;color:inherit;padding:0;border-radius:2px;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  transition:background-color .18s ease,color .18s ease}
.elamin-say.on{background:#ffe066;color:#141414;text-shadow:none;
  box-shadow:0 0 0 3px #ffe066}
/* Inside the highlight, force any nested inline markup (a link, a <strong>, an
   <em> inside the spoken sentence) to the same near-black. Without this a link
   keeps its blue and a heading keeps its own colour, and the passage reads as a
   patchwork — the same low-contrast complaint in a different form.
   `background-color:transparent` is the load-bearing part: a descendant with
   its own opaque background hides the highlight entirely. */
.elamin-say.on *{color:#141414 !important;text-shadow:none !important;
  background-color:transparent !important}
/* A dark scheme is not shipped here, but a page-level filter or a very dark
   section would otherwise leave the highlight invisible; the fallback keeps the
   near-black text with a brighter fill. */
@media (forced-colors:active){
  .elamin-say.on{background:Highlight;color:HighlightText;box-shadow:none;
    forced-color-adjust:none}
  .elamin-say.on *{color:HighlightText !important}
}

@media (max-width:760px){
  /* On a phone the panel must not cover the article. It narrows, and the tab
     shrinks to the 34px header-control size so it does not eat the margin. */
  .er-body{width:240px;max-width:82vw;padding:9px 10px 10px}
  .er-tab{height:32px;padding:0 4px 0 6px}
  .er-tab svg{width:17px;height:17px}
  .er-title{font-size:12px}
  .er-play{width:32px;height:32px}
  .er-play svg{width:17px;height:17px}
}

/* Honor a reduced-motion preference: the slide becomes a cut. */
@media (prefers-reduced-motion:reduce){
  .er-body,.er-tab-x,.elamin-say{transition:none}
}

/* Print: the reader is chrome, never printed, and the highlight should not
   leave a grey band across the page. */
@media print{
  .er{display:none}
  .elamin-say,.elamin-say.on{background:transparent;box-shadow:none}
  /* Restore the page's own colour too: the painted state forces near-black,
     and print must not leave the spoken sentence darker than its paragraph. */
  .elamin-say.on,.elamin-say.on *{color:inherit !important;text-shadow:inherit !important}
}

@media (max-width:760px){
  /* The word "Listen" is the first thing to go: beside a long download filename
     the pill plus its label can wrap the row on a phone, and the icon alone is
     unambiguous in that position. Sizes track the desktop rules (14px/19px
     down to a 40px tap target), which stays above the 32px floor. */
  .listen-btn span{display:none}
  .listen-btn{padding:8px 10px}
  .listen-btn svg{width:21px;height:21px}
  .listen-wrap{margin-left:8px}
  /* The page control tracks the desktop 34px down to 32px -- the tap-target
     floor -- and fits beside the search box at 320px. */
  .listen-page-btn{width:32px;height:32px;margin-right:6px}
  .listen-page-btn svg{width:20px;height:20px}
}

