/* Shared components.
 *
 * Every class here was defined in 2-5 templates before extraction: .wrap in
 * five, .kicker in four, .card/.bicon/.brand in three, and the stance and
 * direction tokens in two each. Duplicating them is exactly how daily.html and
 * duck_symbol.html drifted apart.
 */

/* ---- page column ------------------------------------------------------- */
.wrap {
  max-width: var(--colw, 1400px);
  margin: 0 auto;
  padding: 0 20px var(--sp-7);
}

/* ---- section furniture -------------------------------------------------
 * The eyebrow IS the section separator. Sections are divided by whitespace
 * plus one of these, never by a rule — hairlines mean "these are peer rows".
 */
/* Colour is --duck-deep, not --dim: three of the four templates that carry
 * this class (about, welcome, settings) independently chose the brand green
 * for this exact role, matching --fs-0's own "eyebrow / kicker" comment.
 * daily.html is the deliberate outlier — see its own :root-adjacent rule for
 * why. */
.kicker {
  font-family: var(--mono);
  font-size: var(--fs-1);
  font-weight: var(--w-bold);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--duck-deep);
  margin: var(--sp-1) 0 var(--sp-2);
}

/* max-width matches welcome.html's and settings.html's identical original
 * value; error.html's lede is genuinely bigger (--fs-4, 52ch) and keeps its
 * own override. */
.lede { font-size: var(--fs-2); color: var(--dim); max-width: 56ch; }
/* color is --dim, not --faint: both actual consumers (daily.html,
 * duck_symbol.html) independently chose the more legible grey for "nothing
 * here yet" copy, and font-style:italic is the one property both agreed on
 * that this rule was missing entirely. Padding stays out of this rule on
 * purpose — daily (10px) and duck_symbol (12px) don't even agree with each
 * other, so there is no consensus value to promote. */
.empty { font-size: var(--fs-1); color: var(--dim); font-style: italic; padding: var(--sp-4) 0; }

/* ---- surfaces ----------------------------------------------------------
 * background is --panel (not --paper): of the class's original sources,
 * about.html and duck_symbol.html both independently chose the same subtle
 * off-white (#fafbfc, exactly what --panel is for) over flat white — the
 * same surface daily.html's .analyst/.kpi/.livestrip and duck_admin.html's
 * .preview already use for this identical "raised card on a white page"
 * concept. */
.card {
  background: var(--panel);
  border: 1px solid var(--hair);
  border-radius: var(--r-md);
  padding: var(--sp-4);
}

/* ---- stance -----------------------------------------------------------
 * duck = bullish, cuck = bearish, sit = no edge. Per-symbol views are RAW:
 * "bull SQQQ" means buy SQQQ. Only market-direction AGGREGATES flip for
 * inverse ETFs, and that flip lives in the aggregate code, not here.
 */
.badge, .b-duck, .b-cuck, .b-sit {
  display: inline-block;
  font-size: var(--fs-1);
  font-weight: var(--w-bold);
  border-radius: var(--r-xs);
  padding: 2px var(--sp-2);
  white-space: nowrap;
}
.b-duck { background: var(--duck-bg); color: var(--duck-deep); }
.b-cuck { background: var(--cuck-bg); color: var(--cuck-deep); }
.b-sit  { background: var(--sit-bg);  color: var(--dim); }

/* ---- direction --------------------------------------------------------
 * Same raw-vs-aggregate rule as stance above. */
.up { color: var(--duck-deep); }
.dn { color: var(--cuck-deep); }

/* ---- chips ------------------------------------------------------------
 * Every .chip on the site sits on a DARK hero, so this is a dark-surface
 * pill by default — a light one would be styling for a case that does not
 * exist.
 *
 * This unifies two drifted implementations of the same pill: `.subbanner
 * .chip` (10.5px, border .25, padding 3px 10px) and four leaderboard-hero
 * chips that hardcoded the same component INLINE at 11.5px, border .2,
 * padding 4px 11px. Same pill, two sets of numbers, neither reusable.
 */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-1);
  font-weight: var(--w-mid);
  color: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: var(--r-pill);
  padding: var(--sp-1) var(--sp-3);
}
/* The one chip that carries meaning rather than label. */
.chip--accent { color: #a7f3d0; }

/* ---- brand & icons ----------------------------------------------------- */
.brand {
  font-family: var(--display);
  font-size: var(--fs-2);
  font-weight: var(--w-bold);
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--ink);
}
/* Fixed px, not 1em: daily.html and duck_symbol.html carried byte-identical
 * local copies at 12px/-2px/3px margin — real, agreeing drift from this
 * rule's old 1em, not two independent choices. about.html's 15px is a
 * genuine third variant (a bigger inline mark next to its "Duck"/"Cuck"
 * explainer headings) and keeps its own override. fill:currentColor is kept
 * for robustness even though every current icon-duck/-cuck/-sit def already
 * colours its own paths, so it is a no-op today. */
.bicon { width: 12px; height: 12px; vertical-align: -2px; margin-right: 3px; fill: currentColor; }

/* ---- buttons ----------------------------------------------------------- */
.gbtn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--body);
  font-size: var(--fs-1);
  font-weight: var(--w-bold);
  border: 0;
  border-radius: var(--r-sm);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
}

.sharebar { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ---- ticker identity: logo-or-monogram tile ----------------------------
 * Manifest-gated (Task 4, web/static/js/symlogo.js): an <img> only ever
 * renders for a symbol present in ticker_logos.json's `logos` list; every
 * other symbol — all of them right now, logos ships empty until the
 * operator backfills real logos — gets this sector-tinted monogram. This
 * is the path that has to look right everywhere: symbol hero, hover card,
 * search dropdown, game deal card.
 */
.symlogo { border-radius: var(--r-xs); vertical-align: -3px; }
.mono-tile {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--body); font-weight: var(--w-bold); color: #fff;
  background: var(--dim);
}
/* Sector tints — the 11 GICS sectors plus the site's two non-GICS buckets
 * (common/enums.py Sectors.BROAD_MARKET / VOLATILITY). Nothing in tokens.css
 * covers a 13-way categorical split, and these tiles are UI chrome rather
 * than a data-viz legend, so a muted, brand-adjacent set is enough — every
 * shade below is picked to clear 4.5:1 white-on-tile contrast (relative
 * luminance per WCAG 2.x; ratios noted inline). consumer-discretionary got
 * its own dedicated amber rather than reusing --bill-deep: the token
 * (#d97706) is only 3.19:1 on white and --bill-deep itself must stay
 * unchanged (it's a text/border color elsewhere), so this sector — one of
 * the largest, and every symbol in it renders this exact tile while logos
 * is empty — needed a shade that both clears contrast AND reads as a
 * distinct hue from energy/materials' rust-orange (hue ~23-26°): this one
 * sits at hue ~40° (golden/mustard) instead. */
.mono-tile.sec-information-technology { background: #2563eb; }                    /* 5.17:1 */
.mono-tile.sec-health-care            { background: #0f766e; }                    /* 5.47:1 */
.mono-tile.sec-financials             { background: #7c3aed; }                    /* 5.70:1 */
.mono-tile.sec-consumer-discretionary { background: #8a5d0a; }                    /* 5.75:1 — dedicated, not --bill-deep */
.mono-tile.sec-energy                 { background: #b45309; }                    /* 5.02:1 */
.mono-tile.sec-utilities              { background: #065f46; }                    /* 7.68:1 */
.mono-tile.sec-industrials            { background: #475569; }                    /* 7.58:1 */
.mono-tile.sec-materials              { background: #92400e; }                    /* 7.09:1 */
.mono-tile.sec-communication-services { background: #be185d; }                    /* 6.04:1 */
.mono-tile.sec-consumer-staples       { background: #4d7c0f; }                    /* 4.99:1 */
.mono-tile.sec-real-estate            { background: #0e7490; }                    /* 5.36:1 */
.mono-tile.sec-broad-market           { background: #334155; }                    /* 10.35:1 */
.mono-tile.sec-volatility             { background: #9f1239; }                    /* 8.02:1 */

/* ------------------------------------------------------------------ */
/* Statlist — label + pinned numeric columns (hit rate / edge / n).   */
/* A grid, not flex: long labels wrap inside their own column and the */
/* ch floors keep typical rows aligned; wider content grows its column */
/* First consumer: /analyst cards.                                    */
/* ------------------------------------------------------------------ */
.statlist { font-size: var(--fs-1); }
.statlist .srow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(6ch, auto) minmax(8ch, auto) minmax(6ch, auto);
  column-gap: var(--sp-2);
  align-items: baseline;
  padding: var(--sp-1) 0;
  border-bottom: 1px dashed var(--hair);
}
.statlist .srow:last-child { border-bottom: 0; }
.statlist .who { color: var(--dim); overflow-wrap: anywhere; }
.statlist .num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.statlist .num.n { color: var(--dim); font-size: var(--fs-1); }
.statlist .wide { grid-column: 2 / -1; }
.statlist .span2 { grid-column: 3 / -1; }
.statlist .warm.wide { text-align: right; }

/* ---- Arcade (Beat the AI) shared effects — used by play.html and the
   symbol page's game card. JS partner: static/js/arcade.js. ---- */
@keyframes pulse-dot { 0%, 100% { opacity:1; transform:scale(1); } 50% { opacity:0.4; transform:scale(0.8); } }
@keyframes arcpulse { 50% { opacity:0.5; text-shadow:0 0 30px var(--bill); } }
@keyframes waddle { 0% { transform:rotate(-4deg); } 100% { transform:rotate(4deg) translateY(-1px); } }
@keyframes cardIn { 0% { transform:scale(0.92) translateY(-10px); opacity:0; } 100% { transform:none; opacity:1; } }
@keyframes arcflip { 0% { transform:rotateX(90deg); opacity:0; } 100% { transform:none; opacity:1; } }
.arc-card-enter { animation:cardIn 0.22s cubic-bezier(0.34,1.4,0.64,1); }
.arc-flip { animation:arcflip 0.55s cubic-bezier(0.34,1.4,0.64,1); }
.arc-track { position:relative; height:30px; margin-top:16px; background:rgba(255,255,255,0.03);
             border-radius:var(--r-pill); padding:0 8px; border:1px solid rgba(255,255,255,0.06); }
.arc-track::before { content:""; position:absolute; left:12px; right:30px; top:50%;
                     border-top:1.5px dashed rgba(226,232,240,0.22); }
.arc-duckpos { position:absolute; top:3px; left:0; transition:left 0.9s linear; }
.arc-duck { width:24px; height:24px; filter:drop-shadow(0 2px 4px rgba(0,0,0,0.4)); animation:waddle 0.4s ease-in-out infinite alternate; }
.arc-bell { position:absolute; right:6px; top:3px; font-size:var(--fs-2); filter:drop-shadow(0 0 6px rgba(245,158,11,0.5)); }
.arc-streak-badge { background:linear-gradient(135deg, #f59e0b, #ef4444); color:#fff;
                    font:var(--w-bold) var(--fs-1) var(--mono); padding:2px 8px; border-radius:var(--r-pill);
                    margin-left:8px; box-shadow:0 0 10px rgba(245,158,11,0.4); display:inline-block; }
@media (prefers-reduced-motion: reduce) {
  .arc-duck, .arc-flip, .arc-card-enter { animation:none; }
  .arc-duckpos { transition:none; }
}
/* ---- search palette modal (searchmodal.js) -----------------------------
 * The topbar pill opens this; the old inline input + anchored dropdown are
 * gone. One overlay element under <body>, so it never fights the topbar's
 * stacking or the mobile scroll-fold. z-index clears every in-flow layer —
 * the site tops out at 80 outside the 9999 toasts.
 */
#smodal { position: fixed; inset: 0; z-index: 120; }
#smodal .sm-backdrop { position: absolute; inset: 0; background: rgba(17,24,39,0.35); }
.sm-card { position: relative; margin: 14vh auto 0; width: min(560px, calc(100vw - 32px));
           display: flex; flex-direction: column; max-height: min(64vh, 620px);
           background: var(--paper); border: 1px solid var(--hair); border-radius: var(--r-md);
           box-shadow: 0 24px 64px rgba(17,24,39,0.18); overflow: hidden; }
/* The duck→bill gradient the pill wears, as the head's underline. Two-layer
 * background, not border-image — border-image can't follow a radius. */
.sm-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px;
           border-bottom: 2px solid transparent;
           background: linear-gradient(var(--paper),var(--paper)) padding-box,
                       linear-gradient(105deg,var(--duck),var(--duck-bright) 45%,var(--bill)) border-box; }
.sm-head svg { width: 18px; height: 18px; flex: none; color: var(--dim); }
#sm-input { flex: 1; min-width: 0; border: 0; outline: 0; background: none;
            font: var(--fs-2) var(--body); color: var(--ink); }
/* Cancel is the phone's close affordance (no backdrop to tap when the card
 * is full-screen); desktop has backdrop + Esc, so it hides there. */
.sm-cancel { display: none; border: 0; background: none; color: var(--dim);
             font: var(--fs-1) var(--body); cursor: pointer; padding: 4px 2px; }
/* overscroll contain: html/body overflow:hidden is not a hard lock on iOS
 * Safari — when the list hits its end, touch scroll would chain to the page
 * behind the backdrop. */
.sm-list { overflow-y: auto; padding: 6px 0 10px; overscroll-behavior: contain; }
.sm-sec { display: flex; justify-content: space-between; align-items: baseline;
          font-family: var(--mono); font-size: var(--fs-1); font-weight: var(--w-bold);
          letter-spacing: 1.5px; text-transform: uppercase; color: var(--dim);
          padding: 12px 14px 4px; }
.sm-clear { border: 0; background: none; color: var(--dim); font-family: var(--body);
            font-size: var(--fs-1); letter-spacing: 0; text-transform: none; cursor: pointer; }
.sm-clear:hover { color: var(--ink); }
/* Row recipe carried over from the old dropdown: ticker + name + badge +
 * day change. The logo and sector read as clutter at list size. */
.sm-item { display: flex; align-items: baseline; gap: 10px; padding: 8px 14px;
           cursor: pointer; font-size: var(--fs-1); }
.sm-item.hi, .sm-item:hover { background: var(--soft); }
.sm-item b { font-weight: var(--w-bold); }
.sm-name { color: var(--dim); font-size: var(--fs-1); overflow: hidden;
           text-overflow: ellipsis; white-space: nowrap; max-width: 18ch; }
.sm-px { font-family: var(--mono); font-size: var(--fs-1); margin-left: auto; }
.sm-px.up { color: var(--duck-deep); }
.sm-px.dn { color: var(--cuck-deep); }
.sm-hint { padding: 14px; color: var(--dim); font-size: var(--fs-1); }
/* Open = the page behind must not scroll. Both elements: iOS needs body. */
html.smodal-open, html.smodal-open body { overflow: hidden; }
@media (max-width: 720px) {
  /* Full-screen takeover — input pinned top, sections scroll under it. A
   * centered card leaves half its height under the phone keyboard. */
  .sm-card { margin: 0; width: 100%; height: 100dvh; max-height: none;
             border: 0; border-radius: 0; }
  /* fs-4 (17px): iOS zooms the whole page on focusing any input under 16px. */
  #sm-input { font-size: var(--fs-2); }
  .sm-cancel { display: inline-block; }
  .sm-item { padding: 12px 14px; }   /* finger-size rows */
}

/* Live price tick flash animations & AI intelligence badge styles */
@keyframes tick-flash-up {
  0% { background-color: rgba(16, 185, 129, 0.38); color: #047857; }
  100% { background-color: transparent; }
}
@keyframes tick-flash-down {
  0% { background-color: rgba(239, 68, 68, 0.38); color: #b91c1c; }
  100% { background-color: transparent; }
}
.flash-up { animation: tick-flash-up 1.2s cubic-bezier(0.16, 1, 0.3, 1); border-radius: var(--r-xs); }
.flash-down { animation: tick-flash-down 1.2s cubic-bezier(0.16, 1, 0.3, 1); border-radius: var(--r-xs); }

/* AI Intelligence Violet Glow Badges & Accents */
.ai-badge {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--ai-glow); border: 1px solid var(--ai-border);
  color: var(--ai-violet); border-radius: var(--r-pill);
  padding: 3px 10px; font: var(--w-bold) var(--fs-1) var(--mono);
  letter-spacing: 0.08em; text-transform: uppercase;
}
.ai-badge svg { width: 13px; height: 13px; flex: none; }

/* ---- answered headlines -----------------------------------------------
 * A section title asks a question; `.bh-answer` is the live stat that
 * answers it, set right after the question in the same display face. The
 * gradient IS the stance: duck answers run pond-deep → mint, cuck answers
 * crimson → rose, and plain facts (a count, a timestamp, a name) take the
 * AI violet the site reserves for "the desk's intelligence". No glow, no
 * shadow — the page around it is white and hairlines.
 *
 * inline-block on purpose: the question carries a text-decoration underline
 * and an INLINE child would inherit it, drawing the line under the answer.
 * `:empty` hides the span entirely, so a feed that is down leaves the bare
 * question rather than a dangling gradient or stuck shimmer. Callers set
 * textContent + data-tone and drop `.pending` in one place. */
.bh-answer {
  display: inline-block;
  font-family: var(--display);
  font-weight: var(--w-bold);
  letter-spacing: -0.01em;
  white-space: nowrap;
  --ans-a: var(--ai-violet);
  --ans-b: #c084fc;
  color: var(--ans-a);            /* solid fallback: clipped text needs @supports */
}
.bh-answer[data-tone="duck"] { --ans-a: var(--duck-deep); --ans-b: var(--duck-bright); }
.bh-answer[data-tone="cuck"] { --ans-a: var(--cuck-deep); --ans-b: #f87171; }
.bh-answer[data-tone="ai"]   { --ans-a: var(--ai-violet); --ans-b: #c084fc; }
/* Per-segment tones for a multi-stance answer ("188 Ducks · 134 Cucks ·
 * 101 Sitting"): the parent's gradient is clipped to the PARENT's text box,
 * so a child gets no paint of its own — each segment re-declares its tone
 * and re-clips. `sit` is the one tone the parent never takes: grey, the
 * same --dim the .b-sit badge reads in. The " · " separators between the
 * segments are the parent's own text and keep the leading side's tone. */
.ans-seg[data-tone="duck"] { --ans-a: var(--duck-deep); --ans-b: var(--duck-bright); }
.ans-seg[data-tone="cuck"] { --ans-a: var(--cuck-deep); --ans-b: #f87171; }
.ans-seg[data-tone="ai"]   { --ans-a: var(--ai-violet); --ans-b: #c084fc; }
.ans-seg[data-tone="sit"]  { --ans-a: var(--dim); --ans-b: var(--faint); }
.ans-seg { color: var(--ans-a); }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .bh-answer:not(.pending), .bh-answer:not(.pending) .ans-seg {
    background: linear-gradient(100deg, var(--ans-a) 0%, var(--ans-b) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }
}
.bh-answer:empty:not(.pending) { display: none; }
/* Phones: a 359px sentence ("0 of 12 flagship desks made money today")
 * cannot stay on one line in a 350px column — nowrap pushed it 2px past the
 * column at 390 and on a 320px phone expanded the layout viewport to 391,
 * zooming the whole page out. The answer wraps inside itself here; desktop
 * keeps the one-line read. */
@media (max-width: 720px) {
  .bh-answer { white-space: normal; }
}
/* Pending = the question is on the page and the number is in flight. A low
 * shimmer in the answer's own tone, sized to roughly the text it awaits. */
.bh-answer.pending {
  min-width: 9ch; height: 0.9em; vertical-align: -0.05em;
  border-radius: var(--r-xs);
  color: transparent;
  background: linear-gradient(90deg, var(--soft) 20%, var(--ai-glow) 50%, var(--soft) 80%);
  background-size: 200% 100%;
  animation: ans-shimmer 1.6s ease-in-out infinite;
}
@keyframes ans-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bh-answer.pending { animation: none; background: var(--soft); }
}

/* ---- legal captions ----------------------------------------------------
 * Two lines that recur site-wide (2026-08-21, ahead of the first public
 * sign-ups): the consent line under every Google CTA (_consent.html) and the
 * "not investment advice" line next to every recommended-portfolio promise.
 * One class so the four CTA surfaces and the six promise surfaces cannot
 * drift; dark heroes override the colour locally. Tokens only. */
.legal-note { font-size: var(--fs-1); color: var(--dim); line-height: 1.45; margin: var(--sp-2) 0 0; max-width: 56ch; }
.legal-note a { color: inherit; text-decoration: underline; }

/* ------------------------------------------------------------------ */
/* Tally — a COUNT DRAWN. One mark per session, the winning ones      */
/* filled. Shared by /algos's catalog and /lab's bench so the two     */
/* cannot drift into two different pictures of the same number.       */
/*                                                                    */
/* It is deliberately NOT a sparkline: the payloads carry green-day   */
/* COUNTS (days_pos/days, verdict.green_days/sessions) and never the  */
/* per-session order, so drawing these left-to-right as a chronology  */
/* would be inventing one. The marks are unordered by design, which   */
/* is why they are uniform rather than sequenced.                     */
/*                                                                    */
/* Why it earns its space: "+7.22%" and "+1.20%" sit one line apart   */
/* on a board, and the first was green on 3 sessions of 9 while the   */
/* second was green on 6. A reader sees that difference in the marks  */
/* before they read either number.                                    */
/* ------------------------------------------------------------------ */
.tally {
  display: inline-flex;
  gap: 2px;
  vertical-align: middle;
  margin-right: var(--sp-2);
}
.tally i {
  width: 4px;
  height: 12px;
  background: var(--hair);
  border-radius: var(--r-xs);
}
.tally i.on { background: var(--duck); }

/* ------------------------------------------------------------------ */
/* Site footer — the base recipe, so a page that includes             */
/* _footer.html gets the site's footer without restating twelve       */
/* lines of CSS. It WAS restated twelve times, and four pages that    */
/* never restated it (/, /portfolio, /week, /brag) had no footer at   */
/* all; putting the rule here is what makes the include enough.       */
/*                                                                    */
/* These sheets load before every page's own <style id="page-style">, */
/* so a page that wants a different rule above the fine print         */
/* (/daily's column width, /play's terminal edge, /login's dark       */
/* glass) still wins at equal specificity — same migration contract   */
/* as the rest of this file.                                          */
/* ------------------------------------------------------------------ */
footer {
  border-top: 1px solid var(--hair);
  margin-top: var(--sp-6);
  padding: var(--sp-4) 0 var(--sp-2);
  color: var(--dim);
  font-size: var(--fs-1);
  line-height: 1.6;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
footer a { color: var(--dim); }
footer .fine { max-width: 520px; }

@media (max-width: 720px) {
  footer { flex-direction: column; }
}

/* The footer's sign-in link. It was a bare anchor nothing ever flipped, so
 * signed-in members saw "Sign in" at the bottom of every page (reported
 * 2026-08-21). It rides the header's stamp: paintSubscribe (_topbar.html)
 * sets html[data-sub] to 'in'/'on' when signed in, .auth-out hides and
 * .auth-in (Account -> /settings) takes its place. NOT [data-subwhen] —
 * that keys on SUBSCRIBED, and a signed-in non-subscriber must not be
 * offered Sign in either.
 *
 * These live HERE, not in _topbar.html, because /login and /welcome carry
 * the footer without the topbar. While they sat in the topbar, /login
 * rendered the pair unstyled, as the single word "Sign inAccount".
 * A page that knows its own auth state (/welcome is member-only) can still
 * settle the pair itself in page_style. */
html[data-sub="in"] .auth-out, html[data-sub="on"] .auth-out { display: none; }
.auth-in { display: none; }
html[data-sub="in"] .auth-in, html[data-sub="on"] .auth-in { display: inline; }
