/* =============================================================================
   NEWSY V2 — THE COMPONENTS
   =============================================================================

   The console at index.html is a Tailwind page: neon green on near-black, a
   glow on every edge, twenty accent colours in a drawer. This is the same
   layout — the same hero, the same snapshot card, the same desk strip, story
   of the day and headline grid, in the same order — rebuilt on the house
   system, where the only colours are ten greys and the type does the work
   colour used to.

   WHAT IS NOT HERE
   ----------------
   Everything structural is site.css's and is not repeated: .wrap, .band, .d1,
   .d2, .lede, .eyebrow, .nav, .mode-pill, .menu, .foot, .btn, .field. This
   sheet is only the shapes a wire console needs and the homepage has no
   equivalent for.

   THE TONE LADDER
   ---------------
   Nothing below names a grey. Every ground, hairline and surface reads a
   token, and the ten tones in the control panel are ten sets of those tokens
   written onto <html> by newsy2.js. That is the whole mechanism: a page that
   names #0C1116 anywhere is a page with nine tones that do not work.

       --paper      the ground
       --tint       the whisper above it (alternating bands, panels)
       --deep       the clear step (footer, inverted furniture)
       --sur        a surface on the ground        (cards at rest)
       --sur-2      a surface on a surface         (cards hovered, chips)
       --line       a hairline you are meant to see
       --line-soft  a hairline that only separates

   Both editions define all seven. The paper edition travels DOWN in lightness
   from its ground, the moon edition travels UP — a dark band on a dark page
   disappears, so the step is a lift, not a further descent. That asymmetry is
   the one thing that cannot be expressed as an inversion.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   THE DEFAULT LADDER

   Tone 2 of 10 in each edition — the house values. JS overwrites these on
   <html> the moment it runs, but they are declared here so the page is right
   before it runs and right if it never does.
   -------------------------------------------------------------------------- */
:root {
    --tint:      #FAFAFA;
    --sur:       rgba(30, 38, 43, .025);
    --sur-2:     rgba(30, 38, 43, .055);
    --on-ink:    #ffffff;   /* what sits on an --ink fill */
    --live:      var(--ink);
    --nav-h:     74px;
}

html[data-dark] {
    --ink:       #FFFFFF;
    --ink-77:    rgba(255, 255, 255, .72);
    --ink-55:    rgba(255, 255, 255, .58);
    --line:      rgba(255, 255, 255, .16);
    --line-soft: rgba(255, 255, 255, .09);
    --line-dark: rgba(30, 38, 43, .22);
    --muted:     #8A9199;
    --paper:     #0C1116;
    --tint:      #0F151B;
    --deep:      #1A222C;
    --deep-soft: #212A35;
    --sur:       rgba(255, 255, 255, .03);
    --sur-2:     rgba(255, 255, 255, .065);
    --accent:    #FFFFFF;
    --on-ink:    #0C1116;
    color-scheme: dark;
    background: var(--paper);
}
html[data-dark] body { background: var(--paper); color: var(--ink-77); }

/* -----------------------------------------------------------------------------
   THE PARAGRAPH RESET

   Nearly every <p> on this page is furniture rather than prose — a metric row
   in the snapshot, a stamp beside a section heading, a label in the control
   panel. The user agent's 1em block margins on those are what pulled the
   snapshot card a hundred pixels taller than its own content, with the five
   metric rows drifting apart down the middle of it. Reset once, here, at the
   top, so the components below only ever declare the spacing they actually
   want. Anything that does want a margin restates it — and does so BELOW this
   block, which is why this block is at the top.
   -------------------------------------------------------------------------- */
.ny-live, .ny-snap__row, .ny-stamp, .ny-panel__h, .ny-sec__note { margin: 0; }

/* The accent is a grey. This page is monochrome on purpose — the ten tones
   are the palette, and a warm hairline running through them would be the one
   thing on the page that none of the ten could change. The eyebrow rule, the
   focus ring and the live dot all read this, so they travel with the tone. */
:root { --accent: var(--ink); }

/* =============================================================================
   THE CHROME
   ========================================================================== */

/* The bar. site.css draws it; these are the two things a console adds to it —
   a wordmark that is a property rather than the site, and a row of controls
   that has to survive down to a phone without wrapping into two bars. */
.nav__mark-self { display: flex; flex-direction: column; text-decoration: none; line-height: 1.1; }
.nav__mark-self b {
    font-size: .95rem; font-weight: 700; letter-spacing: -.02em; color: var(--ink);
}
.nav__mark-self span {
    font-size: .58rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--ink-55);
    /* The bar is a single row of fixed height. Let this wrap and "THE STANDARD
       OF TRUTH" becomes two lines, which grows the bar, which moves every
       anchor target on the page down by the difference. It is hidden outright
       below 900px rather than allowed to wrap there. */
    white-space: nowrap;
}

html[data-dark] .nav {
    background: color-mix(in srgb, var(--paper) 86%, transparent);
    border-bottom-color: var(--line-soft);
}

/* The controls cluster. One flex row, gap 1rem to match the house bar, and it
   scrolls rather than wraps — a navbar that becomes two rows on a narrow
   window moves every anchor target on the page by 40px. */
.nav__tools { display: flex; align-items: center; gap: .55rem; flex: 0 0 auto; }

/* ---------------------------------------------------------------- switches --
   The reading switch and the IMM button are the same object at two sizes: a
   track with segments, exactly one lit. Written as one component because they
   read as one control group, sitting next to each other on the bar. */
.ny-seg {
    display: inline-flex; align-items: center; flex: 0 0 auto;
    background: var(--sur); border: 1px solid var(--line);
    border-radius: 999px; padding: 2px;
}
.ny-seg__b {
    appearance: none; -webkit-appearance: none;
    border: 0; background: transparent; cursor: pointer;
    font: inherit; font-size: .59rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--ink-55); padding: .38rem .68rem; border-radius: 999px;
    line-height: 1; white-space: nowrap;
    transition: color .18s var(--ease), background .18s var(--ease);
}
.ny-seg__b:hover { color: var(--ink); }
.ny-seg__b[aria-pressed="true"] { background: var(--ink); color: var(--on-ink); }
.ny-seg__b:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The IMM control. Four states, and the label says which — a button whose
   only feedback is its own colour is a button nobody can read. */
.ny-imm {
    appearance: none; -webkit-appearance: none;
    display: inline-flex; align-items: center; gap: .34rem;
    background: var(--sur); border: 1px solid var(--line);
    /* Sized for one short token now, not a token and a word. */
    border-radius: 999px; padding: .42rem .6rem; cursor: pointer;
    font: inherit; font-size: .59rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase; color: var(--ink-55);
    line-height: 1; white-space: nowrap;
    transition: color .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease);
}
.ny-imm:hover { color: var(--ink); border-color: var(--ink); }
.ny-imm:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* IMM, IMM1, IMM2, IMM3 — three characters at rest and four at every other
   level. Left to size itself the chip would grow and shrink by a character as
   you cycle it, and since it sits mid-row, Admin and Browse live would shuffle
   sideways on every press. Held at the width of the longest of the four. */
.ny-imm b {
    font-weight: 700; font-variant-numeric: tabular-nums;
    /* 3.05em still left IMM2 and IMM3 two pixels wider than IMM and IMM1 —
       tabular-nums asks for even figures but DM Sans has no tabular set to
       give, so 1 stays narrower than 2 and 3. Clamped above the widest of the
       four instead, which does not depend on the font having the feature. */
    min-width: 3.3em; text-align: center;
}
html[data-imm="1"] .ny-imm, html[data-imm="2"] .ny-imm, html[data-imm="3"] .ny-imm {
    background: var(--ink); border-color: var(--ink); color: var(--on-ink);
}
.ny-imm__i { width: 11px; height: 11px; flex: 0 0 auto; display: block; }

/* The two bar buttons on the right of the pic. */
.ny-navbtn {
    display: inline-flex; align-items: center; gap: .4rem;
    text-decoration: none; cursor: pointer;
    font-size: .62rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
    padding: .52rem .9rem; border-radius: 999px;
    border: 1px solid var(--line); color: var(--ink-55); background: transparent;
    font-family: inherit; line-height: 1; white-space: nowrap;
    transition: color .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease);
}
.ny-navbtn:hover { color: var(--ink); border-color: var(--ink); }
.ny-navbtn--fill { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
.ny-navbtn--fill:hover { background: transparent; color: var(--ink); }
.ny-navbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 1180px) { .ny-navbtn--admin { display: none; } }
@media (max-width: 1040px) { .nav__links { display: none; } }
@media (max-width: 900px)  { .ny-navbtn--live { display: none; } .nav__mark-self span { display: none; } }
@media (max-width: 700px)  { .ny-seg--read { display: none; } }
/* The density chip used to carry a second word and drop it under 460px. It no
   longer carries one at any width, so there is nothing left to drop. */

/* =============================================================================
   THE HERO
   ========================================================================== */
.ny-hero { padding-block: clamp(2.4rem, 5vw, 4.2rem) clamp(1.6rem, 3vw, 2.6rem); }
.ny-hero__grid {
    display: grid; gap: clamp(1.8rem, 3.4vw, 3.2rem);
    /* minmax(0,...) on both, or one long unbroken headline in the left column
       sets the width of the right one and the card stops fitting. */
    grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr);
    align-items: center;
}
@media (max-width: 940px) { .ny-hero__grid { grid-template-columns: minmax(0, 1fr); } }

/* The live chip. */
.ny-live {
    display: inline-flex; align-items: center; gap: .55rem;
    border: 1px solid var(--line); border-radius: 999px;
    padding: .34rem .85rem; margin-bottom: 1.5rem;
    font-size: .61rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--ink-55);
    background: var(--sur); max-width: 100%;
}
.ny-live__t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ny-dot {
    width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto;
    background: var(--live); animation: nyPulse 2.4s ease-in-out infinite;
}
@keyframes nyPulse { 0%, 100% { opacity: 1; } 50% { opacity: .28; } }
@media (prefers-reduced-motion: reduce) { .ny-dot { animation: none; } }

.ny-hero h1 {
    font-size: clamp(2.6rem, 7vw, 5.4rem);
    font-weight: 200; letter-spacing: -.045em; line-height: .95;
    color: var(--ink); margin: 0 0 1.4rem;
}
.ny-hero__lede { font-size: clamp(1.02rem, 1.5vw, 1.3rem); line-height: 1.5; font-weight: 300; color: var(--ink-77); margin: 0 0 2rem; max-width: 34ch; }
.ny-hero__acts { display: flex; flex-wrap: wrap; gap: .7rem; margin-bottom: 2rem; }
.ny-hero__foot { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; font-size: .78rem; color: var(--ink-55); }

/* The source dial — three overlapping discs, one per wire that answered, in
   place of the console's stock-photograph avatars. It counts something. */
.ny-dial { display: flex; }
.ny-dial i {
    width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
    border: 1px solid var(--line); background: var(--tint); color: var(--ink);
    font-size: .52rem; font-weight: 800; font-style: normal; letter-spacing: .02em;
    margin-left: -9px; flex: 0 0 auto;
}
.ny-dial i:first-child { margin-left: 0; }

/* ------------------------------------------------------------- the snapshot --
   The card on the right of the pic, line for line: a titled head with a live
   pill, five labelled metrics down the left, one large number on the right,
   and a footer rule. Every figure in it is counted from the wire this page
   just read — see snapshot() in newsy2.js. Nothing here is decorative. */
.ny-snap {
    border: 1px solid var(--line); border-radius: 18px;
    background: var(--tint); padding: 1.05rem 1.15rem;
}
.ny-snap__head { display: flex; align-items: center; justify-content: space-between; gap: .7rem; margin-bottom: .85rem; }
.ny-snap__ttl { display: flex; align-items: center; gap: .5rem; font-size: .72rem; font-weight: 700; letter-spacing: .04em; color: var(--ink); }
.ny-snap__pill {
    display: inline-flex; align-items: center; gap: .4rem;
    border: 1px solid var(--line); border-radius: 999px; padding: .18rem .55rem;
    font-size: .53rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
    color: var(--ink-55); background: var(--sur); white-space: nowrap;
}
.ny-snap__body { display: flex; gap: 1rem; align-items: flex-start; }
.ny-snap__rows { flex: 1 1 auto; min-width: 0; display: grid; gap: .3rem; }
.ny-snap__row { display: flex; gap: .45rem; font-size: .655rem; line-height: 1.35; min-width: 0; }
.ny-snap__k { font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--ink); flex: 0 0 auto; }
.ny-snap__v { color: var(--ink-55); font-variant-numeric: tabular-nums; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ny-snap__big { flex: 0 0 auto; text-align: right; width: 82px; }
.ny-snap__big small { display: block; font-size: .48rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-55); }
.ny-snap__big b {
    display: block; font-size: 2.7rem; line-height: .92; font-weight: 200;
    letter-spacing: -.05em; color: var(--ink); font-variant-numeric: tabular-nums;
}
.ny-snap__foot {
    display: flex; align-items: center; justify-content: space-between; gap: .7rem;
    border-top: 1px solid var(--line-soft); margin-top: .85rem; padding-top: .6rem;
    font-size: .565rem; letter-spacing: .06em; color: var(--ink-55);
}
.ny-snap__foot b { color: var(--ink); font-weight: 800; }

/* =============================================================================
   THE DESK STRIP — TODAY / BUSINESS / INTL / ME / USA
   -----------------------------------------------------------------------------
   Five chips on a track. It scrolls on its own axis rather than wrapping:
   one unwrappable row inside a grid column widens the document and carries
   every fixed element on the page with it.
   ========================================================================== */
.ny-desks {
    display: flex; gap: 2px; padding: 3px; margin-bottom: .9rem;
    background: var(--sur); border: 1px solid var(--line); border-radius: 999px;
    width: max-content; max-width: 100%;
    overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
}
.ny-desks::-webkit-scrollbar { display: none; }
.ny-desks > * { flex: 0 0 auto; }
.ny-desk {
    appearance: none; -webkit-appearance: none; border: 0; background: transparent;
    font: inherit; font-size: .6rem; font-weight: 700; letter-spacing: .13em;
    text-transform: uppercase; color: var(--ink-55); cursor: pointer;
    padding: .42rem .82rem; border-radius: 999px; line-height: 1; white-space: nowrap;
    transition: color .18s var(--ease), background .18s var(--ease);
}
.ny-desk:hover { color: var(--ink); }
.ny-desk[aria-pressed="true"] { background: var(--ink); color: var(--on-ink); }
.ny-desk:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------- story of the day --- */
.ny-sotd {
    display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
    border: 1px solid var(--line); border-radius: 16px;
    padding: .9rem 1.1rem; background: var(--sur);
    text-decoration: none; color: inherit;
    transition: border-color .2s var(--ease), background .2s var(--ease);
}
.ny-sotd:hover { border-color: var(--ink); background: var(--sur-2); }
.ny-sotd:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.ny-sotd__tag {
    flex: 0 0 auto; display: inline-flex; align-items: center;
    background: var(--ink); color: var(--on-ink);
    font-size: .53rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
    padding: .3rem .6rem; border-radius: 999px; white-space: nowrap;
}
.ny-sotd__when { flex: 0 0 auto; font-size: .6rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-55); white-space: nowrap; }
.ny-sotd__body { flex: 1 1 260px; min-width: 0; }
/* Both are <span>, because the row as a whole is one <a> and a block-level
   heading inside a link is not what this is. They are made block-level here,
   and that is not cosmetic: overflow and text-overflow have NO EFFECT on an
   inline box, so the nowrap summary below measured its full 548px inside a
   375px phone, widened the document, and took the sticky bar and the control
   panel out past the right edge with it. One unclippable row is all it takes. */
.ny-sotd__ttl { display: block; font-size: 1.04rem; font-weight: 600; line-height: 1.28; color: var(--ink); letter-spacing: -.015em; }
.ny-sotd__sub {
    display: block; font-size: .78rem; color: var(--ink-55); margin-top: .18rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ny-sotd__go { flex: 0 0 auto; display: flex; align-items: center; gap: .5rem; }

/* =============================================================================
   SECTIONS
   ========================================================================== */
.ny-sec { padding-block: clamp(2.2rem, 4vw, 3.4rem); border-top: 1px solid var(--line-soft); }
.ny-sec--first { border-top: 0; }
.ny-sec__head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1.2rem; flex-wrap: wrap; margin-bottom: 1.5rem;
}
.ny-sec__ttl { display: flex; align-items: baseline; gap: .8rem; flex-wrap: wrap; }
.ny-sec__ttl h2 { font-size: clamp(1.4rem, 2.6vw, 2.05rem); font-weight: 300; letter-spacing: -.035em; color: var(--ink); }
.ny-sec__note {
    font-size: .56rem; font-weight: 800; letter-spacing: .15em; text-transform: uppercase;
    color: var(--ink-55); border: 1px solid var(--line); border-radius: 999px; padding: .22rem .6rem;
    white-space: nowrap;
}
.ny-sec__acts { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.ny-stamp {
    font-size: .55rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-55); font-variant-numeric: tabular-nums; text-align: right; line-height: 1.5;
}
.ny-stamp b { color: var(--ink); font-weight: 800; }

/* ------------------------------------------------------------ the headline --
   A card is a hairline box on the ground, and the only thing lifted off it is
   the headline. The console's version glowed; the glow said nothing the
   ranking did not already say. */
.ny-grid {
    display: grid; gap: 1px;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
    background: var(--line-soft);
    border: 1px solid var(--line-soft);
}
.ny-card {
    display: flex; flex-direction: column; gap: .55rem;
    padding: 1.05rem 1.15rem 1rem; background: var(--paper);
    text-decoration: none; color: inherit; min-width: 0;
    transition: background .2s var(--ease);
}
.ny-card:hover { background: var(--sur); }
.ny-card:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ny-card__top { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
.ny-tag {
    display: inline-flex; align-items: center;
    font-size: .5rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
    color: var(--ink-55); border: 1px solid var(--line); border-radius: 4px; padding: .16rem .38rem;
    white-space: nowrap;
}
.ny-tag--live { border-color: transparent; color: var(--ink); padding-left: 0; padding-right: 0; }
.ny-card__ttl {
    font-size: .96rem; font-weight: 600; line-height: 1.3; letter-spacing: -.015em;
    color: var(--ink); margin: 0;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.ny-card__sum {
    font-size: .8rem; line-height: 1.5; color: var(--ink-55); margin: 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ny-card__foot {
    display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    margin-top: auto; padding-top: .5rem;
    font-size: .6rem; letter-spacing: .05em; color: var(--ink-55);
}
.ny-card__src { font-weight: 700; color: var(--ink-77); }

/* -------------------------------------------------------------- the wire ---
   A story is a row, not a card — the same shape the paper edition uses, kept
   deliberately so the two readings of this property look related. */
.ny-wire { border-top: 1px solid var(--line); }
.ny-wire__row {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .3rem 1rem;
    align-items: baseline; padding: .95rem 0; border-bottom: 1px solid var(--line-soft);
    text-decoration: none; color: inherit;
    transition: background .2s var(--ease);
}
.ny-wire__row:hover { background: var(--sur); }
.ny-wire__row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ny-wire__meta {
    grid-column: 1 / -1; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
    font-size: .555rem; font-weight: 700; letter-spacing: .15em; text-transform: uppercase;
    color: var(--ink-55);
}
.ny-wire__src { color: var(--ink); }
.ny-wire__ttl { font-size: 1rem; font-weight: 500; line-height: 1.35; color: var(--ink); letter-spacing: -.012em; min-width: 0; }
.ny-wire__when { font-size: .62rem; color: var(--ink-55); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ny-wire__sum { grid-column: 1 / -1; font-size: .82rem; color: var(--ink-55); line-height: 1.5; margin: .1rem 0 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* --------------------------------------------------------------- the pulse --
   What the desk is talking about, counted rather than asserted: the terms
   that appear across the most distinct headlines, with the count shown so a
   reader can see how thin or thick the evidence is. */
.ny-pulse { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 210px), 1fr)); gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft); }
.ny-pulse__i { display: flex; align-items: baseline; gap: .6rem; padding: .8rem .95rem; background: var(--paper); min-width: 0; }
.ny-pulse__n { font-size: .62rem; font-weight: 800; color: var(--ink-55); font-variant-numeric: tabular-nums; flex: 0 0 auto; width: 1.6rem; }
.ny-pulse__t { font-size: .88rem; font-weight: 600; color: var(--ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ny-pulse__c { margin-left: auto; font-size: .6rem; color: var(--ink-55); font-variant-numeric: tabular-nums; flex: 0 0 auto; }

/* ------------------------------------------------------------- the probe --- */
.ny-probe__row { display: flex; gap: .6rem; flex-wrap: wrap; margin-bottom: 1rem; }
.ny-probe__row .field { flex: 1 1 320px; min-width: 0; }
.ny-out {
    border: 1px solid var(--line); border-radius: 14px; background: var(--tint);
    padding: 1rem 1.15rem; max-height: 340px; overflow: auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .72rem; line-height: 1.7; color: var(--ink-77);
    white-space: pre-wrap; word-break: break-word;
}
.ny-out b { color: var(--ink); }

/* -------------------------------------------------------------- domains ---- */
.ny-doms { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft); }
.ny-dom {
    display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    padding: .8rem .95rem; background: var(--paper); text-decoration: none; color: inherit; min-width: 0;
    transition: background .2s var(--ease);
}
.ny-dom:hover { background: var(--sur); }
/* The name wins the space. Both are shrinkable, but the department label
   gives way three times as fast — a tile that truncates "domainchaos.com" to
   fit the word PREMIUM on the same line has cropped the only part anyone came
   to read. */
.ny-dom b { flex: 1 1 auto; font-size: .85rem; font-weight: 600; color: var(--ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ny-dom span {
    flex: 0 3 auto; min-width: 0; font-size: .55rem; font-weight: 800; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-55);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------------------------------------------------------------- buttons -- */
.ny-more { display: flex; justify-content: center; margin-top: 1.4rem; }

/* =============================================================================
   THE MINI CONTROL PANEL
   -----------------------------------------------------------------------------
   The console's floating panel, in the house register and with controls that
   mean something on a monochrome page: the edition, the ten tones, the orbs,
   the density, the motion. Collapsed it is a 108px tab; open it is a 320px
   card. Bottom centre, above everything, out of the way of the wire.
   ========================================================================== */
.ny-panel {
    position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%);
    z-index: 80; width: 108px; max-width: calc(100vw - 24px);
    background: var(--tint); border: 1px solid var(--line); border-radius: 16px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, .16);
    overflow: hidden; transition: width .3s var(--ease);
}
html[data-dark] .ny-panel { box-shadow: 0 18px 44px rgba(0, 0, 0, .5); }
.ny-panel.is-open { width: 320px; }
.ny-panel__tab {
    appearance: none; -webkit-appearance: none; width: 100%;
    display: flex; align-items: center; justify-content: center; gap: .4rem;
    background: transparent; border: 0; border-bottom: 1px solid transparent;
    cursor: pointer; font: inherit; padding: .5rem .7rem;
    font-size: .58rem; font-weight: 800; letter-spacing: .17em; text-transform: uppercase;
    color: var(--ink); line-height: 1;
}
.ny-panel.is-open .ny-panel__tab { border-bottom-color: var(--line); }
.ny-panel__tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.ny-panel__tab i { font-style: normal; font-size: .6rem; transition: transform .25s var(--ease); }
.ny-panel.is-open .ny-panel__tab i { transform: rotate(180deg); }
.ny-panel__body { display: none; padding: .9rem 1rem 1rem; }
.ny-panel.is-open .ny-panel__body { display: block; }
.ny-panel__grp + .ny-panel__grp { margin-top: .85rem; padding-top: .85rem; border-top: 1px solid var(--line-soft); }
.ny-panel__h {
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    font-size: .53rem; font-weight: 800; letter-spacing: .15em; text-transform: uppercase;
    color: var(--ink-55); margin-bottom: .5rem;
}
.ny-panel__h em { font-style: normal; color: var(--ink); }
.ny-panel__rowb { display: flex; gap: 3px; }
.ny-panel__rowb .ny-seg { width: 100%; }
.ny-panel__rowb .ny-seg__b { flex: 1 1 0; min-width: 0; justify-content: center; text-align: center; padding-inline: .3rem; }

/* The ten tones. Ten swatches painted with the grounds they set, each one a
   button — the control that had no selected state on the console gets a ring
   here, because with ten near-identical greys nothing else says which one the
   page is wearing. */
.ny-tones { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 4px; }
.ny-tone {
    appearance: none; -webkit-appearance: none; padding: 0; cursor: pointer;
    aspect-ratio: 1; border-radius: 5px; border: 1px solid var(--line);
    transition: transform .16s var(--ease), box-shadow .16s var(--ease);
}
.ny-tone:hover { transform: scale(1.12); }
.ny-tone[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--tint), 0 0 0 3.5px var(--ink); transform: scale(1.12); }
.ny-tone:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* =============================================================================
   THE ORBS — black and white
   -----------------------------------------------------------------------------
   Eight nodes drifting behind the page. On the console they were neon; here
   they are the two colours the page is made of, and the mode chooses which.
   Behind everything, never interactive, and gone entirely under
   prefers-reduced-motion — a decoration that moves is the first thing to go.
   ========================================================================== */
#orbs { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
html[data-orbs="off"] #orbs { display: none; }
.ny-orb {
    position: absolute; width: 20px; height: 20px; border-radius: 50%;
    /* Atmosphere, not furniture. The first pass ran these at .5 opacity with a
       hard edge and a wide glow, and a white disc at that strength drifting
       across a 5rem headline is the brightest thing on the page — the eye goes
       to the decoration instead of the news. Softened until they read as depth
       behind the type rather than as objects in front of it. */
    opacity: .3; filter: blur(1.6px);
    animation: orbFloat 8s ease-in-out infinite alternate, orbPulse 3.2s ease-in-out infinite;
}
.ny-orb--w { background: #fff; box-shadow: 0 0 22px 5px rgba(255, 255, 255, .28); }
.ny-orb--k { background: #000; box-shadow: 0 0 22px 5px rgba(0, 0, 0, .3); }
/* A white orb on white paper and a black one on a black page are both
   invisible, so each mode carries the opposite ground's weight where it needs
   it: the ring is what keeps a same-colour orb legible on its own ground. */
html:not([data-dark]) .ny-orb--w { opacity: .85; border: 1px solid rgba(30, 38, 43, .5); box-shadow: 0 0 16px 3px rgba(30, 38, 43, .12); }
html[data-dark] .ny-orb--k { opacity: .85; border: 1px solid rgba(255, 255, 255, .55); box-shadow: 0 0 16px 3px rgba(255, 255, 255, .1); }
@keyframes orbFloat {
    0%   { transform: translate(0, 0) scale(1); }
    50%  { transform: translate(26px, -34px) scale(1.14); }
    100% { transform: translate(-22px, 26px) scale(.9); }
}
/* This animates opacity, so it OVERRIDES the .3 on .ny-orb and the .85 on the
   two same-ground rules above — an animated property beats a normal
   declaration whatever the specificity. Which means this keyframe, and not the
   rules that look like they set the opacity, is the one that decides how loud
   the orbs are. The same-ground rules earn their visibility with a ring
   instead, because a border is not animated here and therefore survives. */
@keyframes orbPulse { 0%, 100% { opacity: .34; } 50% { opacity: .14; } }
@media (prefers-reduced-motion: reduce) { #orbs { display: none; } }
html[data-motion="off"] #orbs { display: none; }
html[data-motion="off"] * { animation: none !important; transition: none !important; }

/* The page's own content sits above the orb layer — without this the orbs draw
   over the wire rather than behind it, and every headline gets a grey disc
   sliding across it.

   ONLY the two elements that need it. The first version of this rule listed
   .nav, .menu, .to-top and the panel alongside them and set position:relative
   on all six, which quietly un-did four components that were already
   positioned by site.css: the bar stopped being sticky, the menu stopped being
   fixed (so the panel laid itself out in the document flow, below the footer,
   and opening it appeared to do nothing at all), the back-to-top button
   stopped floating, and the control panel came to rest under the footer.

   None of them needed it. Each already carries a z-index far above this
   layer — nav 60, menu 200, to-top 70, panel 80 — and a z-index only applies
   to a positioned element, which every one of them already was. The two that
   genuinely are static, and therefore genuinely would paint underneath, are
   these: */
main, .foot { position: relative; z-index: 1; }

/* =============================================================================
   IMM — THE FOUR DENSITIES
   -----------------------------------------------------------------------------
   Not a class that shrinks some paddings. Four readings of the same document,
   each one removing a whole layer of it, so pressing the button is a decision
   about how much page you want rather than a cosmetic nudge:

     0  FULL     everything
     1  COMPACT  the furniture goes: dial, snapshot prose, card summaries
     2  DENSE    the hero collapses to its headline; cards become wire rows
     3  WIRE     nothing but the stories, full width, one line each

   Each level is expressed by hiding whole elements and re-declaring the two
   or three measures that carry the layout, never by touching a component's
   internals — which is why the levels compose instead of fighting.
   ========================================================================== */
html[data-imm="1"] { --band: clamp(40px, 5vw, 72px); }
html[data-imm="1"] .ny-dial,
html[data-imm="1"] .ny-card__sum,
html[data-imm="1"] .ny-wire__sum,
html[data-imm="1"] .ny-snap__foot { display: none; }
html[data-imm="1"] .ny-hero { padding-block: clamp(1.6rem, 3vw, 2.6rem) 1.2rem; }
html[data-imm="1"] .ny-hero h1 { font-size: clamp(2.1rem, 5vw, 3.8rem); }
html[data-imm="1"] .ny-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }

html[data-imm="2"] { --band: clamp(28px, 3.5vw, 52px); }
html[data-imm="2"] .ny-dial,
html[data-imm="2"] .ny-card__sum,
html[data-imm="2"] .ny-wire__sum,
html[data-imm="2"] .ny-snap__foot,
html[data-imm="2"] .ny-hero__lede,
html[data-imm="2"] .ny-hero__acts,
html[data-imm="2"] .ny-hero__foot,
html[data-imm="2"] .ny-sec__note { display: none; }
html[data-imm="2"] .ny-hero { padding-block: 1.3rem .8rem; }
html[data-imm="2"] .ny-hero h1 { font-size: clamp(1.7rem, 3.4vw, 2.6rem); margin-bottom: .8rem; }
html[data-imm="2"] .ny-hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 300px); align-items: start; }
html[data-imm="2"] .ny-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 218px), 1fr)); }
html[data-imm="2"] .ny-card { padding: .75rem .8rem; gap: .4rem; }
html[data-imm="2"] .ny-card__ttl { font-size: .84rem; -webkit-line-clamp: 4; }
html[data-imm="2"] .ny-sec { padding-block: clamp(1.3rem, 2.4vw, 2rem); }

html[data-imm="3"] { --measure: 1600px; --band: 0px; }
html[data-imm="3"] .ny-hero,
html[data-imm="3"] #snapshot,
html[data-imm="3"] #pulse,
html[data-imm="3"] #probe,
html[data-imm="3"] #domains,
html[data-imm="3"] #subscribe,
html[data-imm="3"] .ny-sotd,
html[data-imm="3"] .ny-sec__note,
html[data-imm="3"] .ny-card__sum,
html[data-imm="3"] .ny-wire__sum,
html[data-imm="3"] .foot__links { display: none; }
html[data-imm="3"] .ny-sec { padding-block: .6rem 1.2rem; border-top: 0; }
html[data-imm="3"] .ny-grid { grid-template-columns: minmax(0, 1fr); gap: 0; border: 0; background: transparent; }
html[data-imm="3"] .ny-card {
    display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) 4.5rem; gap: .9rem;
    align-items: baseline; padding: .5rem .2rem; border-bottom: 1px solid var(--line-soft);
}
/* NOT display:contents. The head holds two chips — the beat and the live mark
   — and contents promotes both of them to grid children, which fills the
   three columns with WORLD, LIVE and the headline and pushes the timestamp
   on to a second row. The head stays one cell and lays its own chips out. */
html[data-imm="3"] .ny-card__top { display: flex; align-items: center; gap: .45rem; }
html[data-imm="3"] .ny-card__ttl { -webkit-line-clamp: 1; font-size: .92rem; font-weight: 500; }
html[data-imm="3"] .ny-card__foot { margin: 0; padding: 0; justify-content: flex-end; }
html[data-imm="3"] .ny-card__foot .ny-card__src { display: none; }
@media (max-width: 640px) {
    html[data-imm="3"] .ny-card { grid-template-columns: minmax(0, 1fr) 4.5rem; }
    html[data-imm="3"] .ny-card__top { grid-column: 1 / -1; }
}

/* =============================================================================
   THE TWO READINGS — normal and verbose
   -----------------------------------------------------------------------------
   Same wires, two documents. NORMAL is the lead and six more, ranked, and
   nothing on the page that is not a story. VERBOSE is the console in the
   picture. Written onto <html> before the first paint by the latch in <head>,
   because a reading that arrives after load is a page that visibly changes
   shape while somebody is looking at it.
   ========================================================================== */
html[data-read="normal"]  [data-verbose] { display: none !important; }
html[data-read="verbose"] [data-normal]  { display: none !important; }

.ny-read { padding-block: clamp(2.4rem, 5vw, 3.8rem) clamp(2rem, 4vw, 3rem); }
.ny-read__head { margin-bottom: clamp(1.6rem, 3vw, 2.4rem); }
.ny-read__lead {
    display: block; text-decoration: none; color: inherit;
    padding-bottom: 1.6rem; border-bottom: 1px solid var(--line);
}
.ny-read__lead h2 {
    font-size: clamp(1.7rem, 4vw, 3rem); font-weight: 300;
    letter-spacing: -.04em; line-height: 1.08; color: var(--ink); margin: .5rem 0 .6rem;
}
.ny-read__lead p { font-size: clamp(.95rem, 1.3vw, 1.1rem); color: var(--ink-55); margin: 0; max-width: 68ch; }
.ny-read__lead:hover h2 { text-decoration: underline; text-underline-offset: 4px; }

/* =============================================================================
   ODDS AND ENDS
   ========================================================================== */
.vh {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--ink); color: var(--on-ink); padding: .7rem 1.1rem; border-radius: 0 0 8px 0;
    font-size: .8rem; font-weight: 700; text-decoration: none;
}
.skip:focus { left: 0; }

/* A wire that has not answered yet, and one that could not. Both say which,
   because an empty panel with no message is indistinguishable from a bug —
   and on this property it has twice BEEN one. */
.ny-state {
    padding: 2rem 1.2rem; text-align: center; color: var(--ink-55);
    font-size: .84rem; border: 1px dashed var(--line); border-radius: 14px;
}
.ny-state b { display: block; color: var(--ink); font-size: .95rem; font-weight: 600; margin-bottom: .35rem; }
.ny-state code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .78rem; background: var(--sur-2); padding: .1rem .3rem; border-radius: 4px;
}
.ny-skel { animation: skelPulse 1.5s ease-in-out infinite; }
@keyframes skelPulse { 0%, 100% { opacity: .38; } 50% { opacity: .8; } }

/* site.css puts the burger's own reset on .nav__burger; a <button> used as a
   menu row still arrives as a framed grey box in Safari, so the rows this
   page builds as buttons get the same reset the house rows have. */
button.menu__row {
    appearance: none; -webkit-appearance: none; background: transparent;
    border: 0; width: 100%; text-align: left; font: inherit; cursor: pointer;
}

/* Every text input on the page. Under 16px iOS Safari zooms the viewport on
   focus, and with the menu anchored to the right edge that zoom carries the
   panel off screen. Matched on the pointer rather than the width: a 1024px
   tablet is a touch device and a 500px desktop window is not. */
@media (pointer: coarse) {
    .field, .menu__q, input[type="search"], input[type="text"], input[type="url"] { font-size: 16px; }
}

/* The footer's version stamp, and the toast host, both come from shared files
   and need nothing here beyond a ground that is not the page's. */
html[data-dark] .foot { background: var(--deep); border-top-color: var(--line-dark); }
html[data-dark] .menu__panel,
html[data-dark] .menu__head,
html[data-dark] .menu__search,
html[data-dark] .menu__foot { background: var(--tint); }
html[data-dark] .menu__panel { border-left-color: var(--line); box-shadow: -24px 0 60px rgba(0, 0, 0, .5); }
html[data-dark] .menu__q { background: var(--sur-2); border-color: rgba(255, 255, 255, .38); color: var(--ink); }
html[data-dark] .menu__q::placeholder { color: var(--ink-55); }
html[data-dark] .menu__q:focus { background: var(--sur-2); border-color: var(--ink); }
html[data-dark] .menu__clear:hover { color: var(--ink); background: var(--sur-2); }
html[data-dark] .menu__x:hover { border-color: var(--ink); color: var(--ink); }
html[data-dark] .skip { background: var(--ink); color: var(--paper); }
html[data-dark] .btn { background: var(--ink); color: var(--paper); }
html[data-dark] .btn:hover { background: rgba(255, 255, 255, .86); color: var(--paper); }
html[data-dark] .btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
html[data-dark] .btn--ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
html[data-dark] .field { background: var(--sur-2); border-color: rgba(255, 255, 255, .34); color: var(--ink); }
html[data-dark] .field::placeholder { color: var(--ink-55); }
html[data-dark] .field:focus { border-color: var(--ink); box-shadow: 0 0 0 3px rgba(255, 255, 255, .08); }
/* =============================================================================
   THE EDITION SWITCH — compacted

   site.css draws this pill for a navbar where it is one of two or three
   controls and can afford to be an object: a 1px ring, a gradient well, an
   inset shadow, 2.5rem per segment and a thumb throwing an 18px drop shadow.
   On THIS bar it sits in a row of five controls — the reading switch, itself,
   IMM, Admin, Browse live — and at 88x34 it was half again the height of
   everything beside it. Three separate edges (the ring, the well's inner
   shadow, the thumb's halo) stacked into what read as a bordered box holding
   two bubbles rather than as one switch with a side lit.

   So: the ring goes, the well goes, the halo goes, and the box is squeezed to
   the same height as the .ny-seg beside it. What is left is the one thing the
   control actually needs — a quiet track with a solid thumb on one half.

   The glyphs stay 13px. That number is written on the <svg> tags as width and
   height as well as here, and it is the same 13 the switch uses everywhere
   else on the site; the compacting is done with the box around them, not by
   shrinking the only part anyone is trying to read.
   ========================================================================== */
/* ---------------------------------------------------------- the reset first --
   THE thing that made it bulky. site.css's .mode-pill__seg was written for an
   <a> and a <span> — the edition switch everywhere else on the site is a link
   to the other document. Here the two editions are ONE document, so the
   segments are <button>s, and a <button> arrives wearing the user agent's own
   2px outset border, its buttonface background and its 13px Arial. That border
   is a second ring inside the pill's own, on both halves: the control read as
   a bordered box holding two bordered bubbles, which is exactly what it looked
   like. It also added ~4px of height and ~3px of width per segment, so the
   pill stood taller than every other control on the bar.

   Same trap as button.menu__row further up this sheet. A house class worn by
   an element it was not written for needs the reset that element never got. */
button.mode-pill__seg {
    appearance: none; -webkit-appearance: none;
    border: 0; background: transparent; font: inherit; cursor: pointer;
}

.nav .mode-pill {
    padding: 2px;
    border: 0;
    background: var(--sur);
    box-shadow: none;
}
.nav .mode-pill__thumb {
    top: 2px; bottom: 2px; left: 2px; width: calc(50% - 2px);
    box-shadow: none;
}
.nav .mode-pill__seg {
    /* 2.5rem -> 1.6rem, and the block padding set so the outer height lands on
       the same ~28px as the reading switch beside it. */
    min-width: 1.6rem; padding: .34rem .42rem;
}
/* "Hard to read" was the unlit half. --ink-55 is the page's quiet ink, correct
   for a summary line and too quiet for a 13px line-drawing that is one of only
   two things the control has to say. The unlit glyph goes to --ink-77 and the
   lit one is a solid ground colour on a solid thumb. */
.nav .mode-pill__seg { color: var(--ink-77); }
.nav .mode-pill__seg.is-on { color: var(--paper); }
.nav .mode-pill:has(.mode-pill__seg:hover) .mode-pill__seg.is-on { color: var(--ink-77); }
.nav .mode-pill:has(.mode-pill__seg:hover) .mode-pill__seg:hover { color: var(--paper); }
.nav .mode-pill__seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The moon edition needs only the thumb and the track restated — everything
   above is already token-driven and travels on its own. */
html[data-dark] .mode-pill { background: var(--sur); border-color: transparent; box-shadow: none; }
html[data-dark] .mode-pill__thumb { background: var(--ink); }
html[data-dark] .mode-pill__seg { color: var(--ink-77); }
html[data-dark] .mode-pill__seg.is-on { color: var(--paper); }
html[data-dark] .mode-pill:has(.mode-pill__seg:hover) .mode-pill__seg.is-on { color: var(--ink-77); }
html[data-dark] .mode-pill:has(.mode-pill__seg:hover) .mode-pill__seg:hover { color: var(--paper); }
html[data-dark] .band--tint { background: var(--tint); }

/* =============================================================================
   THE MODAL

   One dialog component, used by the collection (a domain, its valuation and an
   offer form) and by the story reader. Built on the same two-part shape as the
   house menu — a scrim that dims and a panel that arrives — rather than a
   third pattern nobody has seen before.

   The panel is a column with a fixed head and foot and ONE scrolling middle:
   on a phone the offer form is taller than the viewport, and a dialog that
   scrolls as a whole puts the submit button somewhere below the fold with no
   indication it is there.
   ========================================================================== */
.ny-modal[hidden] { display: none; }
.ny-modal {
    position: fixed; inset: 0; z-index: 220; display: block; overflow: hidden;
}
.ny-modal__scrim {
    position: absolute; inset: 0; background: rgba(17, 22, 28, .55);
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
    opacity: 0; transition: opacity .3s var(--ease);
}
.ny-modal.is-open .ny-modal__scrim { opacity: 1; }
html[data-dark] .ny-modal__scrim { background: rgba(0, 0, 0, .68); }

.ny-modal__panel {
    position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -46%) scale(.985);
    width: min(680px, calc(100vw - 2rem)); max-height: min(88vh, 900px);
    display: flex; flex-direction: column;
    background: var(--tint); border: 1px solid var(--line); border-radius: 20px;
    box-shadow: 0 30px 80px rgba(17, 22, 28, .28);
    opacity: 0; transition: opacity .3s var(--ease), transform .3s var(--ease);
}
html[data-dark] .ny-modal__panel { box-shadow: 0 30px 80px rgba(0, 0, 0, .62); }
.ny-modal.is-open .ny-modal__panel { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.ny-modal__panel:focus, .ny-modal__panel:focus-visible { outline: none; }
@media (prefers-reduced-motion: reduce) {
    .ny-modal__scrim, .ny-modal__panel { transition: none; }
}

.ny-modal__head {
    display: flex; align-items: flex-start; gap: 1rem; flex: 0 0 auto;
    padding: 1.15rem 1.3rem; border-bottom: 1px solid var(--line);
}
.ny-modal__ttl { flex: 1 1 auto; min-width: 0; }
.ny-modal__ttl b {
    display: block; font-size: clamp(1.4rem, 3.2vw, 1.95rem); font-weight: 300;
    letter-spacing: -.035em; line-height: 1.1; color: var(--ink);
    overflow-wrap: anywhere;
}
.ny-modal__ttl span {
    display: block; margin-top: .18rem;
    font-size: .58rem; font-weight: 800; letter-spacing: .15em;
    text-transform: uppercase; color: var(--ink-55);
}
.ny-modal__fig { flex: 0 0 auto; text-align: right; }
.ny-modal__fig b {
    display: block; font-size: clamp(1.2rem, 2.6vw, 1.6rem); font-weight: 300;
    letter-spacing: -.03em; color: var(--ink); font-variant-numeric: tabular-nums;
}
.ny-modal__fig span {
    display: block; font-size: .5rem; font-weight: 800; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-55);
}
.ny-modal__x {
    flex: 0 0 auto; appearance: none; -webkit-appearance: none;
    width: 32px; height: 32px; padding: 0; cursor: pointer;
    display: grid; place-items: center;
    background: transparent; border: 1px solid var(--line); border-radius: 50%;
    color: var(--ink-55);
    transition: color .18s var(--ease), border-color .18s var(--ease);
}
.ny-modal__x:hover { color: var(--ink); border-color: var(--ink); }
.ny-modal__x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ny-modal__x svg { width: 13px; height: 13px; display: block; }

.ny-modal__body {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    padding: 1.25rem 1.3rem; background: var(--paper);
}
.ny-modal__foot {
    flex: 0 0 auto; padding: 1.1rem 1.3rem;
    border-top: 1px solid var(--line); background: var(--tint);
}
.ny-modal__h {
    font-size: .55rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
    color: var(--ink-55); margin: 0 0 .7rem;
}
.ny-modal__sec + .ny-modal__sec { margin-top: 1.5rem; }

/* The ticked list. */
.ny-check { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.ny-check li {
    display: flex; gap: .6rem; align-items: flex-start;
    font-size: .88rem; line-height: 1.45; color: var(--ink-77);
}
.ny-check li::before {
    content: '\2713'; flex: 0 0 auto; color: var(--ink);
    font-weight: 700; font-size: .8rem; line-height: 1.6;
}

/* The valuation table. Two columns, the figure right-aligned and tabular so
   the digits line up down the column. */
.ny-kv {
    border: 1px solid var(--line); border-radius: 12px; padding: .9rem 1rem;
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem 1rem;
    font-size: .85rem;
}
.ny-kv dt { color: var(--ink-77); margin: 0; }
.ny-kv dd { margin: 0; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; }
.ny-kv .ny-kv__sum { border-top: 1px solid var(--line); padding-top: .55rem; font-weight: 700; color: var(--ink); }

/* =============================================================================
   FORMS
   ========================================================================== */
.ny-form { display: grid; gap: .8rem; }
.ny-form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: .8rem; }
.ny-form label {
    display: block; font-size: .55rem; font-weight: 800; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-55); margin-bottom: .35rem;
}
.ny-form .field { width: 100%; }
.ny-form textarea.field { min-height: 76px; resize: vertical; }
.ny-form__note { font-size: .68rem; color: var(--ink-55); margin: 0; }
.ny-form__err { font-size: .74rem; color: var(--ink); font-weight: 600; margin: 0; }
.ny-form__err:empty { display: none; }

/* =============================================================================
   STAT TILES — the snapshot figures
   -----------------------------------------------------------------------------
   The console painted these as eight glowing boxes in six different accent
   colours, one per tile, which made them read as eight unrelated dashboards.
   They are one set of measurements of one thing, so they are one grid of one
   kind of tile, and the only thing that varies between them is the number.
   ========================================================================== */
.ny-tiles {
    display: grid; gap: 1px; background: var(--line-soft);
    border: 1px solid var(--line-soft);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
}
.ny-tile { background: var(--paper); padding: .95rem 1.05rem; min-width: 0; }
.ny-tile__k {
    font-size: .53rem; font-weight: 800; letter-spacing: .15em; text-transform: uppercase;
    color: var(--ink-55); margin: 0 0 .3rem;
}
.ny-tile__v {
    font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 200; letter-spacing: -.045em;
    line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}
.ny-tile__v--word { font-size: clamp(1rem, 1.8vw, 1.25rem); font-weight: 500; letter-spacing: -.02em; line-height: 1.2; }
.ny-tile__s { font-size: .63rem; color: var(--ink-55); margin: .35rem 0 0; line-height: 1.4; }

/* The three toolkit cards. */
.ny-decks { display: grid; gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.ny-deck {
    background: var(--paper); padding: 1.2rem 1.3rem; text-decoration: none; color: inherit;
    display: flex; flex-direction: column; gap: .55rem; min-width: 0;
    transition: background .2s var(--ease);
}
.ny-deck:hover { background: var(--sur); }
.ny-deck b { font-size: 1.05rem; font-weight: 600; letter-spacing: -.02em; color: var(--ink); }
.ny-deck__k { font-size: .53rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-55); }
.ny-deck p { font-size: .82rem; line-height: 1.5; color: var(--ink-55); margin: 0; }
.ny-deck__go { margin-top: auto; padding-top: .5rem; font-size: .62rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink); }

/* =============================================================================
   THE COMPACT HEADLINE LIST — the probe and the explorer both print one
   -----------------------------------------------------------------------------
   A monospace-adjacent row: headline, then a category tag, a date and a link
   mark held right. It scrolls inside its own box rather than growing the page,
   because both of these panels can hold five hundred rows.
   ========================================================================== */
.ny-rows {
    border: 1px solid var(--line); border-radius: 14px; background: var(--tint);
    max-height: 460px; overflow-y: auto; overflow-x: hidden;
}
.ny-row {
    display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: baseline; gap: .5rem .8rem;
    padding: .55rem .85rem; border-bottom: 1px solid var(--line-soft);
    text-decoration: none; color: inherit;
    transition: background .16s var(--ease);
}
.ny-row:last-child { border-bottom: 0; }
.ny-row:hover { background: var(--sur-2); }
.ny-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ny-row__t {
    font-size: .82rem; line-height: 1.4; color: var(--ink); min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ny-row__c {
    font-size: .52rem; font-weight: 800; letter-spacing: .11em; text-transform: uppercase;
    color: var(--ink-55); white-space: nowrap;
}
.ny-row__d { font-size: .58rem; color: var(--ink-55); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ny-rows__empty { padding: 1.6rem 1rem; text-align: center; font-size: .84rem; color: var(--ink-55); }
@media (max-width: 620px) {
    .ny-row { grid-template-columns: minmax(0, 1fr) auto; }
    .ny-row__c { grid-column: 1 / -1; }
}

/* The status strip above a list: a state word, a count, a cache line. */
.ny-status {
    display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
    padding: .7rem .9rem; margin-bottom: .8rem;
    border: 1px solid var(--line); border-radius: 12px; background: var(--sur);
    font-size: .68rem; color: var(--ink-55);
}
.ny-status b { color: var(--ink); font-weight: 700; }
.ny-status__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ink); flex: 0 0 auto; }

/* A row of controls above a panel: a select, a search box, two buttons. */
.ny-bar { display: flex; gap: .6rem; flex-wrap: wrap; align-items: stretch; margin-bottom: .9rem; }
.ny-bar__grow { flex: 1 1 220px; min-width: 0; }
select.field {
    appearance: none; -webkit-appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
    background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
    padding-right: 2.2rem;
}

/* =============================================================================
   THE HEADLINE SEARCH
   -----------------------------------------------------------------------------
   A field with a glyph in it, a clear button and a live count. It filters the
   grid and the wire together — one array, two views — so the two panels can
   never be answering different questions.
   ========================================================================== */
.ny-find { position: relative; display: flex; align-items: center; margin-bottom: 1.1rem; }
.ny-find > svg {
    position: absolute; left: .95rem; width: 15px; height: 15px;
    color: var(--ink-55); pointer-events: none;
}
.ny-find .field { width: 100%; padding-left: 2.5rem; padding-right: 6.5rem; }
.ny-find .field::-webkit-search-cancel-button { display: none; }
.ny-find__x {
    position: absolute; right: 4.6rem; appearance: none; -webkit-appearance: none;
    width: 24px; height: 24px; padding: 0; cursor: pointer; display: grid; place-items: center;
    background: transparent; border: 0; border-radius: 50%; color: var(--ink-55);
}
.ny-find__x[hidden] { display: none; }
.ny-find__x:hover { color: var(--ink); background: var(--sur-2); }
.ny-find__x svg { width: 10px; height: 10px; }
.ny-find__n {
    position: absolute; right: 1rem; font-size: .58rem; font-weight: 800;
    letter-spacing: .12em; text-transform: uppercase; color: var(--ink-55);
    font-variant-numeric: tabular-nums; pointer-events: none;
}

/* A sub-heading inside a section — the snapshot's two tile groups, the pulse's
   story deck. Quieter than the section heading and louder than an eyebrow. */
.ny-sub {
    font-size: .95rem; font-weight: 600; letter-spacing: -.01em; color: var(--ink);
    margin: 1.8rem 0 .8rem;
}
.ny-sub:first-of-type { margin-top: 2rem; }
.ny-note { font-size: .68rem; color: var(--ink-55); margin: .8rem 0 0; line-height: 1.5; }

/* =============================================================================
   THE SOCIAL MARKS

   Search links, and nothing more than that. Every one is a public search URL
   built out of a term or a headline — there is no API behind them, no counts,
   no "9,099k mentions". The console printed that figure beside these and it
   came from nowhere; a link that takes you to the actual search is the honest
   version of the same idea, and it works.
   ========================================================================== */
.ny-social { display: flex; flex-wrap: wrap; gap: .4rem; }
.ny-social a {
    display: inline-flex; align-items: center; gap: .35rem;
    text-decoration: none; white-space: nowrap;
    font-size: .58rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
    color: var(--ink-55); background: var(--sur);
    border: 1px solid var(--line); border-radius: 999px; padding: .34rem .68rem;
    transition: color .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease);
}
.ny-social a:hover { color: var(--ink); border-color: var(--ink); background: var(--sur-2); }
.ny-social a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The pulse row gains its own marks, so a term is both a filter and a way out
   to the platforms carrying it. */
.ny-pulse__i { flex-wrap: wrap; }
.ny-pulse__go {
    appearance: none; -webkit-appearance: none; border: 0; background: transparent;
    padding: 0; margin: 0; font: inherit; cursor: pointer; text-align: left;
    display: flex; align-items: baseline; gap: .6rem; flex: 1 1 auto; min-width: 0;
}
.ny-pulse__go:hover .ny-pulse__t { text-decoration: underline; text-underline-offset: 3px; }
.ny-pulse__go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ny-pulse__soc { display: flex; gap: .25rem; flex: 0 0 auto; }
.ny-pulse__soc a {
    width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%;
    text-decoration: none; font-size: .5rem; font-weight: 800; letter-spacing: 0;
    color: var(--ink-55); border: 1px solid var(--line);
    transition: color .18s var(--ease), border-color .18s var(--ease);
}
.ny-pulse__soc a:hover { color: var(--ink); border-color: var(--ink); }

/* The disclosure that holds the raw feed prober. */
.ny-det { margin-top: 1.2rem; border-top: 1px solid var(--line-soft); padding-top: 1rem; }
.ny-det > summary {
    cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .5rem;
    font-size: .6rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
    color: var(--ink-55);
}
.ny-det > summary::-webkit-details-marker { display: none; }
.ny-det > summary::before { content: '+'; font-size: .85rem; line-height: 1; }
.ny-det[open] > summary::before { content: '\2212'; }
.ny-det > summary:hover { color: var(--ink); }
.ny-det > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* A tile that is a button — the collection's names open a dialog rather than
   an inbox now, so the tag needs the same reset every other button on this
   page needed. */
button.ny-dom {
    appearance: none; -webkit-appearance: none; border: 0; width: 100%;
    font: inherit; text-align: left; cursor: pointer;
}

/* The scroll lock a dialog needs. site.js owns this class for the menu; the
   modals set it too, so the two can never disagree about whether the document
   behind them is allowed to move. */
/* The lock parks the document at a negative offset rather than only hiding
   its overflow, so the scroll position survives the dialog and closing it
   returns you to the row you pressed. newsy2.js sets and clears `top`. */
body.ny-locked { overflow: hidden; position: fixed; width: 100%; }

/* =============================================================================
   THE NEWS STRIPS

   The component is site.css's; these are the two things a NEWS strip needs that
   a portfolio strip does not. The chips are built by newsy2.js.
   ========================================================================== */
#news-strips { margin-block: 0 clamp(1rem, 2vw, 1.6rem); }
html[data-dark] #news-strips { background: var(--tint); }
html[data-dark] .s-chip { background: var(--paper); }
html[data-dark] .s-chip:hover { background: var(--sur-2); border-color: var(--ink); }
/* A headline is longer than a property name, so the chip has to stop growing
   somewhere or one long story sets the width of the whole track. */
#news-strips .s-name {
    max-width: 30ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The second row travels the other way, so the two do not read as one long
   belt moving past. */
#news-strips .strip-row:nth-child(2) .strip-track { animation-direction: reverse; animation-duration: 150s; }
html[data-motion="off"] #news-strips .strip-track { animation: none; }

/* The V1/V2 switch. Same segmented shape as the reading switch beside it —
   it is the same kind of choice, one of two readings of one property. */
.ny-seg--ver .ny-seg__b { text-decoration: none; }
.ny-seg--ver [aria-current="page"] { background: var(--ink); color: var(--on-ink); cursor: default; }
@media (max-width: 760px) { .ny-seg--ver { display: none; } }
