/* ================================================================
   spo.css — the Palefò Spò EDITORIAL layer
   ================================================================
   This is the language INSIDE the device screen. NervalFrost
   (nervalfrost.css) owns the page chrome around it; the two never
   share tokens, which is why every custom property here is --spo-*.

   Why they differ on purpose:
   NervalFrost is a soft periwinkle operator surface — lavender
   hairlines, 16px radii, frosted panels. The Spò screen is the
   opposite: flat white, 2px black rules, one hot red, square
   corners. That is a deliberate product decision from the deck —
   selection state is "a 2px black border plus a red-tinted fill,
   legible in sunlight, which matters for a phone used outdoors in
   Port-au-Prince." Soft lavender on a white ground disappears at
   noon; black-on-white with a red fill does not.

   Do not "harmonise" these two palettes. The contrast between the
   operator chrome and the product screen is the point.
   ================================================================ */

:root {
  /* The deck's palette (Palefo_Spo_Walkthrough.pdf): flat white, near-black
     ink, 2px black rules, one hot red, square corners. Deliberately NOT
     harmonised with nervalfrost.css — see the header above. */
  --spo-ink: #111111;
  --spo-ink-2: #5a5a5a;
  --spo-ink-3: #8b8b8b;
  --spo-paper: #ffffff;
  --spo-frost: #ffffff;
  --spo-wash: #f2f2f2;
  --spo-red: #ee2d0f;
  --spo-red-tint: #fdece9;
  --spo-rule: #dcdcdc;
  --spo-rule-hard: #111111;
  --spo-accent: var(--spo-red);   /* the deck has one accent, and it is red */

  /* Square corners throughout, per the deck. Kept as tokens so rules added
     since the NervalFrost detour still resolve. */
  --spo-radius: 0;
  --spo-radius-sm: 0;
  --spo-radius-pill: 0;

  --spo-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --spo-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── Device frame ───────────────────────────────────────────────
   430x932 is the deck's canvas. The frame is fixed; only .spo-body
   scrolls, so the status bar, tab strip and bottom nav stay put the
   way they do on a real phone.                                    */
.spo-device {
  width: 400px;
  height: 800px;
  max-height: calc(100dvh - 132px);
  background: var(--spo-paper);
  border: 2px solid var(--spo-rule-hard);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--spo-sans);
  color: var(--spo-ink);
  box-shadow: 0 24px 60px -28px rgba(84, 44, 194, 0.45);
}
@media (max-width: 900px) { .spo-device { width: 100%; max-width: 430px; } }

.spo-statusbar {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 14px 4px;
  font-size: 11px; font-weight: 600; letter-spacing: -0.01em;
  flex-shrink: 0;
}
.spo-statusbar .spo-signal { letter-spacing: 2px; font-size: 9px; color: var(--spo-ink); }

.spo-body { flex: 1; overflow-y: auto; overscroll-behavior: contain; }
.spo-body::-webkit-scrollbar { width: 0; }

/* ── Type scale ─────────────────────────────────────────────────── */
.spo-h1 { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
.spo-h2 { font-size: 16px; font-weight: 650; letter-spacing: -0.01em; }
.spo-sub { font-size: 12px; color: var(--spo-ink-2); line-height: 1.45; }
.spo-kicker {
  font-family: var(--spo-mono); font-size: 9px; font-weight: 500;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--spo-ink-3);
}
.spo-kicker.is-red { color: var(--spo-accent); }
/* A translation the server's checks flagged (board #1584): a kicker that is
   also the way to report it. */
.spo-review { display: inline-block; margin-top: 5px; padding: 0; border: 0; background: none;
  color: var(--spo-accent); cursor: pointer; text-align: left; }
.spo-pad { padding: 16px; }
.spo-stack > * + * { margin-top: 10px; }

/* ── Brand mark: the deck's red square ──────────────────────────── */
.spo-mark { width: 34px; height: 34px; background: var(--spo-red); flex-shrink: 0; }
.spo-mark.is-sm { width: 17px; height: 17px; }

/* ── Progress rail (onboarding, 3 steps) ────────────────────────── */
.spo-steps {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px 0; flex-shrink: 0;
}
.spo-steprail { display: flex; gap: 5px; padding: 6px 14px 10px;
                border-bottom: 2px solid var(--spo-rule-hard); flex-shrink: 0; }
.spo-steprail i { flex: 1; height: 3px; background: var(--spo-rule); }
.spo-steprail i.is-on { background: var(--spo-red); }

/* ── Choice rows (language picker) ──────────────────────────────── */
.spo-choice {
  border-radius: var(--spo-radius-sm);
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 13px 14px; background: var(--spo-paper);
  border: 1px solid var(--spo-rule); font: 500 13px var(--spo-sans);
  color: var(--spo-ink); cursor: pointer; text-align: left;
}
.spo-choice:hover { border-color: var(--spo-ink-3); }
.spo-choice.is-on {
  border: 2px solid var(--spo-rule-hard);
  background: var(--spo-red-tint);
  font-weight: 650;
}
.spo-choice .spo-tick { color: var(--spo-red); font-weight: 700; }

/* ── Chips (sports, leagues) ────────────────────────────────────── */
.spo-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.spo-chip {
  border-radius: var(--spo-radius-pill);
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 12px; background: var(--spo-paper);
  border: 1px solid var(--spo-rule); font: 500 12px var(--spo-sans);
  color: var(--spo-ink); cursor: pointer;
}
.spo-chip:hover { border-color: var(--spo-ink-3); }
/* 2px black + red tint — the sunlight-legible selection state. */
.spo-chip.is-on { border: 2px solid var(--spo-rule-hard); background: var(--spo-red-tint); font-weight: 650; }
.spo-chip.is-local::after { content: "AYITI"; font: 500 8px var(--spo-mono);
                            letter-spacing: .1em; color: var(--spo-red); }

.spo-group { margin-top: 16px; }
.spo-group > .spo-kicker { padding-bottom: 6px; border-bottom: 1px solid var(--spo-rule-hard);
                           margin-bottom: 10px; display: block; }

/* ── Buttons ────────────────────────────────────────────────────── */
.spo-cta {
  border-radius: var(--spo-radius-pill);
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 15px 16px; background: var(--spo-red); color: #fff;
  border: 0; font: 650 13px var(--spo-sans); cursor: pointer; flex-shrink: 0;
}
.spo-cta:hover { filter: brightness(1.07); }
.spo-cta:disabled { background: var(--spo-ink-3); cursor: default; filter: none; }
.spo-btn {
  border-radius: var(--spo-radius-pill);
  padding: 8px 11px; background: var(--spo-paper); border: 1px solid var(--spo-rule-hard);
  font: 500 11px var(--spo-sans); color: var(--spo-ink); cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; justify-content: center;
}
.spo-btn:hover { background: var(--spo-wash); }
.spo-btn.is-dark { background: var(--spo-ink); color: #fff; border-color: var(--spo-ink); }
.spo-btn.is-red { background: var(--spo-paper); color: var(--spo-red); border-color: var(--spo-red); }
.spo-btn:disabled { opacity: .4; cursor: default; }
.spo-btn.is-wide { width: 100%; }

/* ── Feed ───────────────────────────────────────────────────────── */
.spo-appbar {
  display: flex; align-items: center; gap: 9px; padding: 8px 14px;
  border-bottom: 1px solid var(--spo-rule); flex-shrink: 0;
}
.spo-appbar h1 { font-size: 13px; font-weight: 700; letter-spacing: .01em; }
/* The back-arrow bar of a detail or edit page stays reachable while the
   page scrolls (board #1588). */
.spo-appbar.is-sticky { position: sticky; top: 0; z-index: 6; background: var(--spo-paper); }

/* ── Editing from Me (board #1588) ──────────────────────────────── */
.spo-edit-body { padding-bottom: 8px; }
.spo-savebar-wrap { position: sticky; bottom: 0; z-index: 6; padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
                    background: var(--spo-paper); border-top: 1px solid var(--spo-rule); }
.spo-savebar { display: block; width: 100%; padding: 14px 16px; border-radius: 0; cursor: pointer;
               font: 650 13px var(--spo-sans); letter-spacing: .02em; text-align: center;
               border: 2px solid var(--spo-rule); background: var(--spo-paper); color: var(--spo-ink-3);
               transition: color .15s, border-color .15s, background .15s; }
.spo-savebar.is-ready { border-color: var(--spo-accent); color: var(--spo-accent); }
.spo-savebar.is-saving { background: var(--spo-accent); border-color: var(--spo-accent); color: #fff; }
.spo-savebar:disabled { cursor: default; }
.spo-savebar.is-ready:disabled { cursor: pointer; }
.spo-dialog-wrap { position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .45);
                   display: flex; align-items: flex-end; justify-content: center; }
.spo-dialog { width: 100%; max-width: 430px; background: var(--spo-paper);
              padding: 18px 16px calc(18px + env(safe-area-inset-bottom, 0px));
              display: flex; flex-direction: column; gap: 10px; }
.spo-dialog .spo-h2 { margin-bottom: 4px; }
.spo-mgrow { display: flex; align-items: center; gap: 10px; padding: 9px 14px; border-bottom: 1px solid var(--spo-rule); }
.spo-mgrow .spo-avatar { overflow: hidden; }
.spo-mgrow .spo-avatar img { width: 100%; height: 100%; object-fit: contain; }
.spo-mgrow-main { flex: 1; min-width: 0; }
.spo-mgrow-main b { display: block; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spo-mgrow-main span { font-size: 11px; color: var(--spo-ink-3); }
/* Pale orange when off, filled orange when on — star and bell alike. */
.spo-mgrow .spo-toggle { color: var(--spo-accent); opacity: .45; }
.spo-mgrow .spo-toggle.is-on { opacity: 1; }
.spo-appbar .spo-spacer { flex: 1; }

.spo-tabs { display: flex; gap: 16px; padding: 0 14px;
            border-bottom: 2px solid var(--spo-rule-hard); flex-shrink: 0; }
.spo-tab {
  padding: 9px 0 7px; background: none; border: 0; border-bottom: 2px solid transparent;
  margin-bottom: -2px; font: 500 12px var(--spo-sans); color: var(--spo-ink-3); cursor: pointer;
}
.spo-tab.is-on { color: var(--spo-ink); font-weight: 650;
                 border-bottom-color: var(--spo-accent); }
/* The live dot before "Ap Viv" (board #1590). Its box is fixed (7px plus the
   gap) so the pulse never moves the label or the tabs beside it; only
   opacity and transform animate, which the compositor handles without a
   layout pass. Values: 1.8 s loop, ease-in-out, opacity 1 -> .35, scale
   1 -> .8. Orange is the brand token, not a new colour. Reduced motion:
   a steady dot at full opacity. */
.spo-tab-dot { display: inline-block; width: 7px; height: 7px; margin-right: 6px; vertical-align: 1px;
               border-radius: 50%; background: var(--spo-accent);
               animation: spo-tab-pulse 1.8s ease-in-out infinite; will-change: opacity, transform; }
@keyframes spo-tab-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.8); } }
@media (prefers-reduced-motion: reduce) { .spo-tab-dot { animation: none; opacity: 1; transform: none; } }

.spo-post { padding: 13px 14px; border-bottom: 1px solid var(--spo-rule); }
.spo-post-head { display: flex; gap: 9px; align-items: flex-start; }
.spo-avatar {
  width: 34px; height: 34px; background: var(--spo-wash); border: 1px solid var(--spo-rule);
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  font: 500 7px var(--spo-mono); color: var(--spo-ink-3); text-align: center;
  line-height: 1.1; overflow: hidden; padding: 2px;
}
/* With a logo the chip goes white and the text hides — most outlet marks
   are designed for a white ground, and ESPN's is black on transparent. The
   image is `contain`ed, never cropped: a wordmark cut in half is worse
   than a small one. */
.spo-avatar.has-logo { background: #fff; padding: 3px; }
.spo-avatar.has-logo .spo-avatar-txt { display: none; }
.spo-avatar img { width: 100%; height: 100%; object-fit: contain; display: block; }
.spo-meta { font-size: 11px; color: var(--spo-ink-3); display: flex;
            flex-wrap: wrap; align-items: baseline; gap: 5px; }
.spo-meta b { color: var(--spo-ink); font-weight: 650; font-size: 12px; }
.spo-verified { color: var(--spo-accent); font-size: 10px; }
/* The source-language stamp. On every post, always — a reader deciding
   whether to trust a translation needs to know what it came FROM.       */
.spo-lang {
  font: 500 9px var(--spo-mono); letter-spacing: .08em; padding: 1px 4px;
  border: 1px solid var(--spo-rule); color: var(--spo-ink-2);
}
.spo-text { font-size: 13.5px; line-height: 1.48; margin-top: 7px; }
.spo-text.is-ht { }

.spo-photo {
  border-radius: var(--spo-radius-sm);
  margin-top: 9px; background: var(--spo-wash); border: 1px solid var(--spo-rule);
  aspect-ratio: 16/9; display: flex; align-items: flex-end; padding: 8px;
  font: 500 8px var(--spo-mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--spo-ink-3); background-size: cover; background-position: center;
}

/* "Baze sou chwa w" — personalisation made legible, per the deck. */
.spo-why {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 8px;
  padding: 3px 7px; border: 1px solid var(--spo-red); color: var(--spo-red);
  font: 600 8.5px var(--spo-mono); letter-spacing: .07em; text-transform: uppercase;
}

/* The three controls, always in the same place, on every post type. */
.spo-controls { display: flex; gap: 6px; margin-top: 10px; }
.spo-controls .spo-btn:first-child { flex: 1; }


/* Score card
   The tint and the row shape below were in this stylesheet from the start,
   written for a component that did not exist yet (board #1427). Building it
   meant adopting that design rather than inventing a second one — a score
   card being tinted is what separates it from wire copy at a glance.

   Deliberately quieter than a news post: no avatar, no engagement row, no
   translate control. There is nothing to translate on a scoreline. */
/* A card like the others, on the lavender disc rather than paper so it still
   reads as "not a headline" at a glance. The red tint it used to carry is
   gone: red now means LIVE and nothing else, and tinting every fixture — most
   of them not yet kicked off — spent that signal on nothing. A match actually
   in progress gets the red edge instead. */
.spo-score { background: var(--spo-red-tint); border-bottom: 1px solid var(--spo-rule);
             padding: 11px 14px; cursor: pointer; transition: background .12s; }
.spo-score:hover { background: #fbdfda; }
.spo-score.is-live { background: var(--spo-red-tint);
                     border-color: rgba(238, 45, 15, .35); }
.spo-score-row { display: flex; justify-content: space-between; align-items: center;
                 padding: 3px 0; font-size: 13px; font-weight: 600; }
.spo-score-row .spo-goals { font-variant-numeric: tabular-nums; font-size: 15px; }

.spo-score-head { display: flex; align-items: center; justify-content: space-between;
                  gap: 8px; margin-bottom: 7px; }
.spo-score-head .spo-kicker { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* On a live card the kicker ends in the minute — "… · AP VIV 58'" — and the
   minute is the one thing on the card that changes. Beside a long league
   name the venue was taking the room and the kicker was cut to "AP VI…";
   the venue drops to its own line instead. */
.spo-score.is-live .spo-score-head { flex-wrap: wrap; row-gap: 3px; }
.spo-score.is-live .spo-score-head .spo-kicker { flex-shrink: 0; max-width: 100%; }
.spo-score.is-live .spo-score-head .spo-score-venue { max-width: 100%; }
.spo-kickoff { font-family: var(--spo-mono); font-size: 10.5px;
               color: var(--spo-ink-3); flex-shrink: 0; }

.spo-live { display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
            font-family: var(--spo-mono); font-size: 9.5px; letter-spacing: .08em;
            text-transform: uppercase; color: var(--spo-red); }
.spo-live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--spo-red);
                animation: spo-pulse 1.6s ease-in-out infinite; }
@keyframes spo-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
/* A pulsing dot is decoration to anyone who cannot see it move, and a
   distraction to anyone who asked the system to stop animating. */
@media (prefers-reduced-motion: reduce) { .spo-live-dot { animation: none } }

/* A post pinned under a live match (deck, Etap 05): the red live pill with
   the running score and the provider's minute. Red means LIVE and nothing
   else on this screen, same rule as the score card's edge. */
.spo-live-pill { display: inline-flex; align-items: center; gap: 6px; margin-top: 7px;
                 padding: 3px 8px; border-radius: 3px; background: var(--spo-red); color: #fff;
                 font-family: var(--spo-mono); font-size: 9.5px; letter-spacing: .06em;
                 text-transform: uppercase; }
.spo-live-pill .spo-live-dot { background: #fff; }
.spo-live-pill.is-soon { background: var(--spo-wash); color: var(--spo-ink-2); }
.spo-live-pill.is-soon .spo-live-dot { display: none; }
/* The deck's two pills under an Ap viv post: "■ GÒL · 58'" in red beside
   "ARS 2–1 CHE" outlined. A non-goal event (VAR, a red card, an injury) is
   the quiet grey of the deck's "VAR · 76'" — news, not a celebration. */
.spo-text.is-head { font-weight: 650; margin-bottom: 3px; }
.spo-text.is-head + .spo-text { margin-top: 0; }
.spo-pills { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 7px; }
.spo-pills .spo-live-pill { margin-top: 0; }
.spo-live-pill.is-quiet { background: var(--spo-wash); color: var(--spo-ink-2);
                          border: 1px solid var(--spo-rule); }
.spo-live-pill.is-quiet .spo-live-dot { display: none; }
.spo-score-pill { display: inline-flex; align-items: center; padding: 3px 8px;
                  border: 1px solid var(--spo-rule-hard); border-radius: 3px; color: var(--spo-ink);
                  font-family: var(--spo-mono); font-size: 9.5px; letter-spacing: .06em;
                  text-transform: uppercase; font-variant-numeric: tabular-nums; }
/* The score card's head, deck Etap 05: "■ PREMIER LEAGUE · AP VIV 65'" in
   red while the match is on, the venue on the right when the provider
   gives one, the kickoff time before the match. */
.spo-kicker.is-live { color: var(--spo-red); display: inline-flex; align-items: center; gap: 5px; }
.spo-score-venue { font-family: var(--spo-mono); font-size: 9px; letter-spacing: .08em;
                   text-transform: uppercase; color: var(--spo-ink-3); flex-shrink: 1;
                   max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spo-score-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.spo-score .spo-why { margin-top: 7px; }
/* "REZIME MACH LA" — the deck's second chip on the score card, outlined
   grey where BAZE SOU CHWA W is red: an action, not a personalisation. */
button.spo-why.is-quiet { border-color: var(--spo-ink-3); color: var(--spo-ink-2);
                          background: none; cursor: pointer; }
button.spo-why.is-quiet:hover { border-color: var(--spo-ink); color: var(--spo-ink); }

/* Honest degradation, reader side. When a source failed the feed says so in
   one muted line rather than letting "nothing right now" stand for "the
   provider is down". Kept small: it is a status, not an error banner. */
/* Pull to refresh. The empty state has always said "rale pou aktyalize"; on
   the handset, where the desktop chrome's refresh button is hidden, this is
   the only way to do it. A strip above the feed grows with the pull and
   turns solid when letting go will refresh. */
.spo-pull { height: 0; overflow: hidden; display: flex; align-items: flex-end; justify-content: center;
            font: 500 11px var(--spo-mono); letter-spacing: .06em; text-transform: uppercase;
            color: var(--spo-ink-3); background: var(--spo-wash); transition: height .15s ease-out;
            flex-shrink: 0; }
.spo-pull > span { padding-bottom: 8px; }
.spo-pull.is-ready { color: var(--spo-red); }
.spo-pull-arrow { display: inline-block; margin-right: 6px; transition: transform .15s ease-out; }
.spo-pull.is-ready .spo-pull-arrow { transform: rotate(180deg); }
.spo-pull.is-loading .spo-pull-arrow { animation: spo-spin .7s linear infinite; }
.spo-pull.is-loading { color: var(--spo-red); }

/* ── The sticky feed header (board #1587) ─────────────────────────────
   The search row and the tab row stick together to the top of .spo-body,
   the scroller: visible at any depth, both directions, no scroll listener
   moving anything. Opaque paper behind, a hairline where posts pass
   beneath. No ancestor between here and .spo-body carries overflow,
   transform or filter, so sticky holds (the device frame's overflow:hidden
   is on .spo-device, outside the scroller). The "↑ New posts" button is
   absolutely positioned off the block's bottom edge, so it follows the
   header's real height in every language and width. */
.spo-feedhead { position: sticky; top: 0; z-index: 6; background: var(--spo-paper);
                box-shadow: 0 4px 10px -8px rgba(0, 0, 0, .35); }
.spo-feedhead .spo-filter { margin-top: 8px; }
.spo-newposts { position: absolute; left: 50%; bottom: -36px; transform: translateX(-50%); z-index: 6;
                border: 0; background: var(--spo-accent); color: #fff; padding: 7px 14px; cursor: pointer;
                font: 600 11px var(--spo-sans); letter-spacing: .04em; text-transform: uppercase;
                white-space: nowrap; box-shadow: 0 8px 18px -8px rgba(0, 0, 0, .5); }
.spo-newposts:hover { filter: brightness(.95); }
/* Desktop refresh: a pointer that hovers has no pull gesture. */
.spo-refresh-btn { display: none; border: 0; background: none; cursor: pointer; flex-shrink: 0;
                   font-size: 15px; line-height: 1; padding: 0 2px; color: var(--spo-ink-3); }
.spo-refresh-btn:hover { color: var(--spo-red); }
@media (hover: hover) and (pointer: fine) { .spo-refresh-btn { display: inline-block; } }
/* The bottom of a continuous feed (board #1585). */
.spo-feed-foot { padding: 16px 14px 22px; text-align: center; font: 500 10.5px var(--spo-mono);
                 letter-spacing: .06em; text-transform: uppercase; color: var(--spo-ink-3);
                 display: flex; align-items: center; justify-content: center; gap: 8px; }
.spo-feed-foot.is-quiet { padding: 10px; }
.spo-loading.is-inline { width: 14px; height: 14px; margin: 0; }
.spo-feed-note { display: flex; align-items: center; justify-content: space-between; gap: 10px;
                 padding: 8px 14px; font-size: 12px; background: var(--spo-wash);
                 border-bottom: 1px solid var(--spo-rule); }
.spo-feed-note.is-error { color: var(--spo-red); }

/* ── Ap viv · glise sou spò ─────────────────────────────────────────
   The feed slides sideways, one sport per panel. The track is a native
   horizontal scroller with mandatory snap, so touch gets the platform's
   own momentum and settle; the scrollbar is hidden because the dots are
   the scrollbar. overscroll-behavior-x stops a swipe past the last
   panel from turning into browser back-navigation on Android. */
.spo-slides { display: flex; flex-direction: column; }
/* The carousel is pinned under the top tabs while the feed scrolls (spec).
   position:sticky inside .spo-body, the vertical scroller; paper behind it
   so the feed does not show through the gap beside a peeking card. */
.spo-live-pin { position: sticky; top: 0; z-index: 3; background: var(--spo-paper);
                border-bottom: 1px solid var(--spo-rule); }
.spo-live-pin .spo-slide-bar { padding: 4px 14px 8px; }
.spo-live-feed .spo-slide-head { border-top: 1px solid var(--spo-rule); padding-top: 12px; }
.spo-score-venue.is-line { max-width: none; margin-bottom: 6px; }
.spo-slide-bar { display: flex; align-items: center; justify-content: space-between;
                 padding: 9px 14px 6px; }
.spo-slide-dots { display: flex; gap: 5px; }
/* A dash, not a dot — the deck's pager is 18×4, and a dash is a stronger
   target at this size than a circle. Red is the tab's own colour: on this
   screen it already means "now". */
.spo-slide-dot { width: 18px; height: 4px; padding: 0; border: 0; border-radius: 2px;
                 background: var(--spo-rule-hard); cursor: pointer; }
.spo-slide-dot.is-on { background: var(--spo-red); }
.spo-slide-dot:focus-visible { outline: 2px solid var(--spo-red); outline-offset: 2px; }
.spo-slide-navs { display: flex; align-items: center; gap: 6px; }
.spo-slide-count { font: 500 11px var(--spo-mono); color: var(--spo-ink-3);
                   margin-right: 4px; }
.spo-slide-nav { width: 24px; height: 24px; display: inline-flex; align-items: center;
                 justify-content: center; padding: 0; border: 1px solid var(--spo-rule);
                 border-radius: 50%; background: var(--spo-paper); color: var(--spo-ink);
                 cursor: pointer; }
.spo-slide-nav:hover { background: var(--spo-wash); }
.spo-slide-nav:disabled { color: var(--spo-ink-3); cursor: default; background: none; }
.spo-slide-nav:focus-visible { outline: 2px solid var(--spo-red); outline-offset: 1px; }

.spo-slider { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px 4px; position: relative;
              overflow-x: auto; overflow-y: hidden;
              scroll-snap-type: x mandatory; scroll-padding-left: 14px;
              overscroll-behavior-x: contain;
              scrollbar-width: none; cursor: grab; outline: none; }
.spo-slider::-webkit-scrollbar { display: none; }
.spo-slider.is-dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.spo-slider:focus-visible { box-shadow: inset 0 0 0 2px var(--spo-red); }
/* One card per swipe, a little narrower than the track so the next card
   peeks in from the right — the sliver is what says "this scrolls". Each
   snaps at its leading edge. position:relative on the track makes a card's
   offsetLeft relative to the track, which is what the scroller reads.
   min-width:0 matters: a long headline inside would otherwise widen the
   card past its basis and break the one-card-per-swipe rhythm. */
.spo-slide { flex: 0 0 calc(100% - 28px); min-width: 0; scroll-snap-align: start;
             scroll-snap-stop: always; border: 1px solid var(--spo-rule);
             background: var(--spo-paper); }
.spo-slide .spo-post { border-bottom: 0; }
/* An event panel: the score card is the panel's head, its posts follow.
   The card keeps its own top rule off so it sits flush in the frame, and
   the posts under it are ruled from each other as in the stream. */
.spo-slide > .spo-score { border-top: 0; }
.spo-slide .spo-post + .spo-post { border-top: 1px solid var(--spo-rule); }
.spo-slide-head { display: flex; align-items: center; justify-content: space-between;
                  gap: 8px; padding: 10px 14px 2px; }
.spo-slide-sport { display: inline-flex; align-items: center; gap: 6px;
                   font-size: 12px; color: var(--spo-ink); }
.spo-slide-sport b { font-weight: 650; }

.spo-score-row .spo-crest { width: 20px; height: 20px; flex-shrink: 0; border-radius: 3px;
                            background-size: contain; background-repeat: no-repeat;
                            background-position: center; }
.spo-score-row .spo-crest.is-blank { background: var(--spo-rule); }
.spo-score-row .spo-team-name { flex: 1; min-width: 0; font-weight: 500;
                                color: var(--spo-ink-2); overflow: hidden;
                                text-overflow: ellipsis; white-space: nowrap; }
.spo-score-row .spo-goals { color: var(--spo-ink-3); min-width: 18px; text-align: right; }
/* The leading side is the one thing a glance is actually for. */
.spo-score-row.is-lead .spo-team-name { color: var(--spo-ink); font-weight: 700; }
.spo-score-row.is-lead .spo-goals { color: var(--spo-ink); font-weight: 700; }

.spo-score-status { font-size: 11px; color: var(--spo-ink-3); margin-top: 7px;
                    padding-top: 7px; border-top: 1px solid var(--spo-rule); }
.spo-score-src { font-family: var(--spo-mono); font-size: 9.5px; letter-spacing: .06em;
                 text-transform: uppercase; color: var(--spo-ink-3); margin-top: 4px; }

/* ── Skò · match yo pou jounen an (board #1569) ─────────────────────
   A list, not cards: one column of times, two of names, the shape every
   scores app shares so it needs no learning. Live rows carry the red edge
   and a red clock — red still means "happening now" and nothing else.
   Team rows are the score card's own, shrunk. */
.spo-sched { margin: 6px 10px 10px; background: var(--spo-paper);
             border: 1px solid var(--spo-rule); border-radius: var(--spo-radius);
             overflow: hidden; }
/* Wraps: the Kreyòl kicker and three chips do not share 372px, and a
   truncated "MATCH YO POU JOUNEN A…" is worse than a second line. */
.spo-sched-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
                  gap: 6px 8px; padding: 10px 14px 8px; }
.spo-sched-head .spo-kicker { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spo-sched-days { display: flex; gap: 4px; flex-shrink: 0; }
.spo-sched-day { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
                 border: 1px solid var(--spo-rule); border-radius: var(--spo-radius-pill);
                 background: none; color: var(--spo-ink-3); cursor: pointer;
                 font: 600 8.5px var(--spo-mono); letter-spacing: .07em; text-transform: uppercase; }
.spo-sched-day.is-on { background: var(--spo-ink); border-color: var(--spo-ink); color: #fff; }
.spo-sched-day:disabled { opacity: .4; cursor: default; }
.spo-sched-day:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: 1px; }
.spo-sched-n { font-weight: 500; opacity: .75; }
/* The second row of the reference: what state the matches are in. Quieter
   than the day chips above it — outlined, never filled black — so the two
   rows do not read as one. Only the live chip takes colour. */
.spo-sched-status { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 14px 9px; }
.spo-sched-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
                  border: 1px solid var(--spo-rule); border-radius: var(--spo-radius-pill);
                  background: none; color: var(--spo-ink-3); cursor: pointer;
                  font: 600 8.5px var(--spo-mono); letter-spacing: .07em; text-transform: uppercase; }
.spo-sched-chip.is-on { background: var(--spo-wash); border-color: var(--spo-ink-3); color: var(--spo-ink); }
.spo-sched-chip.is-live:not(:disabled) { color: var(--spo-red); }
.spo-sched-chip.is-live.is-on { border-color: var(--spo-red); }
.spo-sched-chip:disabled { opacity: .4; cursor: default; }
.spo-sched-chip:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: 1px; }
/* A button now: tapping the competition folds it. The name takes the first
   line with the count and the chevron; "Baze sou chwa w · …" repeats the
   name at length, and beside it the name itself was cut to "CONCAC…", so
   the tag wraps to a line of its own. */
.spo-sched-league { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 8px; width: 100%;
                    padding: 8px 14px 4px; border: 0; border-top: 1px solid var(--spo-rule);
                    background: none; text-align: left; cursor: pointer; color: inherit; font: inherit; }
.spo-sched-league:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: -2px; }
.spo-sched-league .spo-kicker { flex: 1 0 calc(100% - 64px); min-width: 0; overflow: hidden;
                                text-overflow: ellipsis; white-space: nowrap; }
.spo-sched-league .spo-why { order: 5; margin-top: 0; max-width: 100%; }
.spo-sched-count { flex-shrink: 0; min-width: 18px; padding: 1px 5px; border-radius: var(--spo-radius-pill);
                   background: var(--spo-wash); color: var(--spo-ink-3); text-align: center;
                   font: 600 9px var(--spo-mono); }
.spo-sched-count.is-live { color: var(--spo-red); }
.spo-sched-fold { flex-shrink: 0; color: var(--spo-ink-3); font-size: 10px; line-height: 1; }
.spo-sched-group.is-folded .spo-sched-league { padding-bottom: 8px; }
.spo-sched-row { display: grid; grid-template-columns: 58px 1fr auto; align-items: center; gap: 8px;
                 width: 100%; padding: 7px 14px; border: 0; border-top: 1px solid var(--spo-rule);
                 background: none; text-align: left; cursor: pointer; color: inherit; font: inherit;
                 transition: background .12s; }
.spo-sched-row:hover { background: var(--spo-wash); }
.spo-sched-row:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: -2px; }
.spo-sched-row.is-live { box-shadow: inset 3px 0 0 var(--spo-red); }
/* The provider's own word — "Halftime", "Postponed" — wraps rather than
   truncates: a status cut to "Halfti…" says less than no status. */
.spo-sched-when { font: 500 10px var(--spo-mono); color: var(--spo-ink-3); line-height: 1.25;
                  overflow-wrap: anywhere; }
.spo-sched-row.is-live .spo-sched-when { color: var(--spo-red); font-weight: 600; }
.spo-sched-teams { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.spo-sched-teams .spo-score-row { padding: 0; }
.spo-sched-teams .spo-crest { width: 16px; height: 16px; }
.spo-sched-teams .spo-team-name { font-size: 12px; }
.spo-sched-teams .spo-goals { font-size: 12.5px; min-width: 16px; }
.spo-sched-empty { padding: 18px 14px; text-align: center; color: var(--spo-ink-3);
                   font-size: 12px; border-top: 1px solid var(--spo-rule); }
.spo-sched-src { padding: 7px 14px 9px; border-top: 1px solid var(--spo-rule); margin-top: 0; }

/* ── Skò · the match browser as a page (board #1574) ───────────────
   The list was a card under the Ap viv carousel; it is the whole screen
   now, so it loses the card's margin and border and gains a day bar that
   holds a stepper either side of the day chips and a date field for any
   other day in the window. */
.spo-sched.is-page { margin: 0; border: 0; border-radius: 0; }
.spo-sched.is-page .spo-sched-head { position: sticky; top: 0; z-index: 2; background: var(--spo-paper);
                                     border-bottom: 1px solid var(--spo-rule); padding: 10px 14px; }
.spo-sched.is-page .spo-sched-status { padding: 9px 14px; }
.spo-sched-days { flex-wrap: wrap; align-items: center; }
.spo-sched-step { width: 22px; height: 22px; border: 1px solid var(--spo-rule); background: none;
                  cursor: pointer; color: var(--spo-ink-2); font: 500 13px var(--spo-sans); line-height: 1; }
.spo-sched-step:hover:not(:disabled) { border-color: var(--spo-ink); color: var(--spo-ink); }
.spo-sched-step:disabled { opacity: .35; cursor: default; }
.spo-sched-step:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: 1px; }
.spo-sched-date { height: 22px; padding: 0 5px; border: 1px solid var(--spo-rule); background: var(--spo-paper);
                  color: var(--spo-ink-2); font: 500 10px var(--spo-mono); border-radius: 0; }
.spo-sched-date:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: 1px; }
/* The sport row (board #1577): chips in one line that scrolls sideways,
   an arrow at each end for a mouse, the chosen sport filled black like the
   chosen day. The arrows sit over the ends of the track so the row keeps
   its full width for the chips. */
.spo-sports { position: relative; display: flex; align-items: center; padding: 10px 0 0;
              border-bottom: 1px solid var(--spo-rule); background: var(--spo-paper); }
.spo-sports-track { display: flex; gap: 6px; padding: 0 14px 10px; overflow-x: auto;
                    scroll-snap-type: x proximity; scroll-padding: 0 14px; scrollbar-width: none;
                    overscroll-behavior-x: contain; flex: 1; min-width: 0; }
.spo-sports-track::-webkit-scrollbar { display: none; }
.spo-sport { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; padding: 6px 11px;
             border: 1px solid var(--spo-rule); border-radius: var(--spo-radius-pill); background: none;
             color: var(--spo-ink-2); cursor: pointer; scroll-snap-align: start;
             font: 600 11px var(--spo-sans); white-space: nowrap; }
.spo-sport.is-on { background: var(--spo-ink); border-color: var(--spo-ink); color: #fff; }
.spo-sport:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: 2px; }
.spo-sport-icon { font-size: 13px; line-height: 1; }
.spo-sports-arrow { position: absolute; top: 10px; bottom: 10px; width: 26px; border: 0;
                    background: linear-gradient(to right, var(--spo-paper) 55%, transparent);
                    color: var(--spo-ink); cursor: pointer; font: 500 16px var(--spo-sans); z-index: 1; }
.spo-sports-arrow.is-prev { left: 0; }
.spo-sports-arrow.is-next { right: 0; background: linear-gradient(to left, var(--spo-paper) 55%, transparent); }
.spo-sports-arrow[hidden] { display: none; }
.spo-sched-country { color: var(--spo-ink-3); font-weight: 500; }
.spo-sched-teams .spo-why.is-row { margin-top: 4px; align-self: flex-start; }
.spo-sched-empty.is-down { color: var(--spo-ink-2); }
.spo-sched-empty .spo-sched-day.is-next { margin: 10px 3px 0; color: var(--spo-ink); border-color: var(--spo-ink-3); }
.spo-sched-down-src { margin-top: 6px; font: 500 9px var(--spo-mono); letter-spacing: .06em; color: var(--spo-ink-3); }
/* A race or a tournament day: one name where two sides would be. */
.spo-score-row.is-event .spo-team-name { white-space: normal; }
/* Ap viv with nothing on: said in the carousel's place, not left blank. */
.spo-live-none { margin: 10px 14px; padding: 18px 14px; border: 1px dashed var(--spo-rule);
                 text-align: center; color: var(--spo-ink-3); font-size: 12px; }
/* A match, opened: the provider's facts under the card, one to a line. */
.spo-event-facts { padding: 4px 14px 16px; }
.spo-event-fact { padding: 9px 0; border-bottom: 1px solid var(--spo-rule);
                  font-size: 12.5px; color: var(--spo-ink-2); line-height: 1.4; }
.spo-sched-prov { display: flex; flex-direction: column; gap: 3px; align-items: flex-end; }
.spo-sched-prov:empty { display: none; }
.spo-score-src .spo-prov { margin-left: 6px; }

.spo-prov.is-genre { color: var(--spo-ink-2); border-color: var(--spo-ink-3); }

/* ── Preview, post screen, lightbox (board #1578) ────────────────── */
.spo-post.is-preview { cursor: pointer; }
.spo-post.is-preview:hover { background: var(--spo-wash); }
.spo-more { color: var(--spo-accent); font-weight: 600; white-space: nowrap; }
/* The picture, small in the stream — a strip, not the whole photo — and
   the photo itself on the post's screen, where it is a button. */
.spo-photo.is-thumb { aspect-ratio: auto; height: 120px; background-size: cover;
                      background-position: center; }
.spo-photo.is-open { cursor: zoom-in; }
.spo-photo.is-open:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: 2px; }
.spo-video { display: block; width: 100%; margin-top: 9px; background: #000;
             border: 1px solid var(--spo-rule); }
.spo-source { margin: 0 14px; padding: 12px 0; border-top: 1px solid var(--spo-rule); }
.spo-source-who { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.spo-source-name { font-size: 13px; }
.spo-source-name span { color: var(--spo-ink-3); }
.spo-source-link { display: block; text-align: center; text-decoration: none; }
/* Star and bell (board #1580): 44px targets, the accent token for both
   states — a pale outline off, filled on. */
.spo-source-who { gap: 10px; }
.spo-source-name { flex: 1; min-width: 0; }
.spo-source-toggles { display: flex; gap: 2px; margin-left: auto; flex-shrink: 0; }
.spo-toggle { flex: 0 0 44px; width: 44px; min-width: 44px; height: 44px; min-height: 44px; padding: 0;
              display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
              border: 0; background: none; cursor: pointer; color: var(--spo-accent); opacity: .5; }
.spo-source-toggles { align-self: center; }
.spo-toggle .spo-ico svg { fill: none; }
.spo-toggle.is-on { opacity: 1; }
.spo-toggle.is-on .spo-ico svg { fill: var(--spo-accent); }
.spo-toggle:focus-visible { outline: 2px solid var(--spo-accent); outline-offset: -4px; }
.spo-recommend { margin-top: 14px; }
.spo-recommend .spo-kicker { display: block; margin-bottom: 8px; }
.spo-recommend-chip { display: inline-flex; align-items: center; gap: 4px; color: var(--spo-ink); }
.spo-recommend-chip .spo-ico { color: var(--spo-accent); opacity: .6; display: inline-flex; }
.spo-recommend-chip .spo-ico svg { width: 14px; height: 14px; fill: none; }
.spo-recommend-handle { color: var(--spo-ink-3); font-weight: 500; }
.spo-source-hint { margin-bottom: 10px; font-size: 11.5px; }
.spo-also { margin-top: 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.spo-also .spo-kicker { width: 100%; }
.spo-also-link { font-size: 12px; color: var(--spo-ink); text-decoration: underline; text-underline-offset: 2px; }
.spo-btn.is-barred { opacity: .55; cursor: not-allowed; font-size: 11px; }
/* The per-post translation chooser (board #1581): the buttons, then the
   language chips beneath when the chooser is open. */
.spo-translate { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.spo-translate-row { display: flex; gap: 6px; }
.spo-translate-row .spo-btn { flex: 1; min-width: 0; }
.spo-btn.is-open { border-color: var(--spo-ink); }
.spo-translate-chips { margin: 0; }
.spo-chip.is-off { opacity: .5; cursor: not-allowed; }
.spo-lightbox { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center;
                justify-content: center; padding: 16px; background: rgba(0, 0, 0, .92);
                cursor: zoom-out; }
.spo-lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; }
.spo-lightbox-close { position: absolute; top: 12px; right: 12px; width: 36px; height: 36px;
                      border: 1px solid rgba(255, 255, 255, .5); background: none; color: #fff;
                      font: 400 22px var(--spo-sans); line-height: 1; cursor: pointer; }

/* ── Audio player ───────────────────────────────────────────────── */
.spo-player { background: var(--spo-red-tint); border-top: 1px solid var(--spo-rule);
              border-bottom: 1px solid var(--spo-rule); padding: 12px 14px; }
.spo-player-row { display: flex; align-items: center; gap: 10px; }
.spo-playbtn { width: 42px; height: 42px; background: var(--spo-red); color: #fff;
               border: 0; font-size: 15px; cursor: pointer; flex-shrink: 0; }
.spo-wave { flex: 1; display: flex; align-items: flex-end; gap: 2px; height: 32px; }
.spo-wave i { flex: 1; background: var(--spo-rule); min-height: 3px; }
.spo-wave i.is-played { background: var(--spo-ink); }
.spo-wave i.is-head { background: var(--spo-red); }
.spo-times { display: flex; justify-content: space-between; margin-top: 5px;
             font: 500 10px var(--spo-mono); color: var(--spo-ink-3); }

/* ── Bottom nav ─────────────────────────────────────────────────── */
.spo-nav { display: flex; border-top: 2px solid var(--spo-rule-hard); flex-shrink: 0; }
.spo-nav button {
  flex: 1; padding: 12px 0; background: var(--spo-paper); border: 0;
  font: 600 10px var(--spo-mono); letter-spacing: .11em; color: var(--spo-ink-3); cursor: pointer;
}
.spo-nav button.is-on { color: var(--spo-accent); }
/* Version strip under the nav. Mono and ink-3 like the nav labels so it reads
   as chrome, not content; hairline above so it does not float. */
.spo-footer { flex-shrink: 0; padding: 4px 0 6px; text-align: center;
              border-top: 1px solid var(--spo-rule); }
.spo-ver { font: 500 9.5px var(--spo-mono); letter-spacing: .08em; color: var(--spo-ink-3); }
.spo-ver:empty { display: none; }

/* ── Notes, disclosure ──────────────────────────────────────────── */
.spo-note { border-left: 3px solid var(--spo-red); background: var(--spo-red-tint);
            padding: 9px 11px; font-size: 11.5px; line-height: 1.5; }
.spo-disclosure { font-size: 10px; color: var(--spo-ink-3); line-height: 1.45; margin-top: 8px; }
.spo-quote { border-left: 3px solid var(--spo-red); padding: 5px 0 5px 10px;
             font-size: 12.5px; line-height: 1.5; }
.spo-quote + .spo-quote { margin-top: 9px; }


.spo-row { display: flex; align-items: center; justify-content: space-between;
           padding: 12px 0; border-bottom: 1px solid var(--spo-rule); font-size: 13px; }
.spo-row:last-child { border-bottom: 0; }
.spo-row .spo-val { color: var(--spo-ink-3); font-size: 12px; }

/* Toggle */
.spo-toggle { width: 40px; height: 21px; background: var(--spo-rule); border: 0;
              cursor: pointer; position: relative; flex-shrink: 0; }
.spo-toggle.is-on { background: var(--spo-red); }
.spo-toggle::after { content: ""; position: absolute; top: 2px; left: 2px;
                     width: 17px; height: 17px; background: #fff; transition: transform .14s; }
.spo-toggle.is-on::after { transform: translateX(19px); }

/* ── States ─────────────────────────────────────────────────────── */
.spo-empty { padding: 40px 20px; text-align: center; color: var(--spo-ink-3); font-size: 12.5px; }
.spo-loading { padding: 30px 20px; text-align: center; }
.spo-loading::after {
  content: ""; display: inline-block; width: 15px; height: 15px;
  border: 2px solid var(--spo-rule); border-top-color: var(--spo-red);
  border-radius: 50%; animation: spo-spin .7s linear infinite;
}
@keyframes spo-spin { to { transform: rotate(360deg); } }
.spo-busy { opacity: .45; pointer-events: none; }

/* Provenance flag — a fixture is never allowed to look like live data. */
.spo-prov { font: 500 8px var(--spo-mono); letter-spacing: .09em; text-transform: uppercase;
            color: var(--spo-ink-3); border: 1px dashed var(--spo-rule); padding: 1px 4px; }

/* Muted club badge for a roster row past its review window. */
.spo-stale { color: var(--spo-ink-3); font-style: italic; }

@media (prefers-reduced-motion: reduce) {
  .spo-loading::after { animation: none; }
  .spo-toggle::after { transition: none; }
}

/* Language dropdown inside a settings row. The control comes from the platform
   stylesheet (nervalfrost), so it is restyled here to the product's own tokens
   rather than importing operator chrome into the reader app — the two sheets
   are deliberately not harmonised. */
.spo-row .nf-langsw {
  appearance: none; -webkit-appearance: none;
  background: var(--spo-wash); color: var(--spo-ink);
  border: 1px solid var(--spo-rule); border-radius: 0;
  font: 12px var(--spo-sans); padding: 6px 24px 6px 9px; min-width: 140px;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", var(--spo-sans);
  background-image: linear-gradient(45deg, transparent 50%, var(--spo-ink-2) 50%),
                    linear-gradient(135deg, var(--spo-ink-2) 50%, transparent 50%);
  background-position: right 11px top 47%, right 6px top 47%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.spo-row .nf-langsw:focus { outline: 2px solid var(--spo-red); outline-offset: 1px; }

/* Icon-only button in the app bar (the settings gear). A 32px square hit
   target with no border: the bar's chrome is the rule beneath it, and a pill
   outline around a lone glyph read as a second brand mark. Lights up in the
   accent while a settings screen is open, the way the MWEN tab does. */
.spo-iconbtn {
  width: 32px; height: 32px; margin: -4px -6px -4px 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 50%;
  color: var(--spo-ink-2); cursor: pointer;
}
.spo-iconbtn:hover { background: var(--spo-wash); color: var(--spo-ink); }
.spo-iconbtn.is-on { color: var(--spo-red); }
.spo-iconbtn:focus-visible { outline: 2px solid var(--spo-red); outline-offset: 1px; }

/* Inline icon inside a control button. vertical-align keeps the glyph on the
   text baseline rather than sitting a pixel proud of it. */
.spo-ico { display: inline-flex; align-items: center; vertical-align: -3px; }
.spo-ico svg { display: block; }

/* Play-all sits in the tab row and acts on whatever the row is showing. It is
   pushed to the end rather than sized to match a tab: it is a verb among
   nouns, and making it look like a fifth tab would invite a tap expecting a
   fifth feed. */
.spo-tabs { align-items: center; }
.spo-playall { margin-left: auto; display: inline-flex; align-items: center; gap: 5px;
               background: none; border: 1px solid var(--spo-rule); border-radius: 0;
               padding: 4px 10px; cursor: pointer; flex-shrink: 0;
               font: 600 10.5px var(--spo-sans); letter-spacing: .04em;
               text-transform: uppercase; color: var(--spo-ink-2); }
.spo-playall:hover { border-color: var(--spo-ink-3); color: var(--spo-ink); }
.spo-playall.is-on { background: var(--spo-red); border-color: var(--spo-red); color: #fff; }
.spo-playall span { font-family: var(--spo-mono); letter-spacing: 0; text-transform: none; }

/* ── Feed filter ─────────────────────────────────────────────────────
   Sits above the tab menu because it acts on all of them: switching tab
   keeps the filter, and the count next to it says how much it is hiding. */
.spo-filter {
  display: flex; align-items: center; gap: 7px;
  margin: 8px 10px 0; padding: 6px 10px;
  background: var(--spo-paper); border: 1px solid var(--spo-rule);
  border-radius: 0; flex-shrink: 0;
}
.spo-filter-icon { font-size: 14px; color: var(--spo-ink-3); line-height: 1; flex-shrink: 0; }
.spo-filter-input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none; padding: 2px 0;
  font: 400 13px var(--spo-sans); color: var(--spo-ink);
}
.spo-filter-input::placeholder { color: var(--spo-ink-3); }
.spo-filter-count {
  font: 500 10.5px var(--spo-mono); color: var(--spo-ink-3); flex-shrink: 0;
}
.spo-filter-clear {
  border: 0; background: none; cursor: pointer; flex-shrink: 0;
  font-size: 16px; line-height: 1; padding: 0 2px; color: var(--spo-ink-3);
}
.spo-filter-clear:hover { color: var(--spo-red); }
