/* =============================================================================
   NEXUS — labs.llc/nexus/
   =============================================================================

   The property's own sheet. It loads AFTER assets/css/site.css, which brings
   the tokens, the navbar, the hamburger, the footer and the type; everything
   here is the stage, the readouts and the written section beneath them.

   NOT ONE COLOUR IS A LITERAL. Every value below is a house token or a value
   derived from one, which is the whole reason the dark edition is a palette
   swap and not a second stylesheet: assets/css/dark.css repoints --ink,
   --paper, --line and --accent under html[data-dark] and this file follows
   without being told.

   The exception, and it is a real one: the CANVAS cannot read a CSS variable.
   Its palette lives in js/nexus.js and is chosen from the same data-dark hook.
   The two have to be kept in step by hand, and the note is here because this
   is the file somebody will be looking at when they wonder why the cosmos did
   not change colour.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens --
   Three of our own, all derived. --stage-h is stated once because four rules
   need to agree about it. */
:root {
    --nx-stage-h:   calc(100svh - var(--nav-h));
    --nx-hud-bg:    color-mix(in srgb, var(--paper) 78%, transparent);
    --nx-hud-line:  var(--line);
}
html[data-dark] {
    /* On the deep ground the panels have to sit ON the cosmos, so they are a
       shade of the ground rather than a shade of the paper. */
    --nx-hud-bg: color-mix(in srgb, #0C1116 72%, transparent);
}

/* ----------------------------------------------------------------- stage -- */
.nx-stage {
    position: relative;
    height: var(--nx-stage-h);
    min-height: 420px;
    /* The ground the canvas is cleared to. The canvas paints it too; this is
       what shows in the half-second before the first frame. */
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    overflow: hidden;
    /* A drag on the stage steers the field rather than scrolling the page.
       That is only safe because the stage is not the whole viewport on a
       phone — see the media query at the foot of this file. */
    touch-action: none;
    isolation: isolate;
}
html[data-dark] .nx-stage { background: #0C1116; }

.nx-stage canvas {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    z-index: 0;
}

/* The custom ring. It is only ever shown for a real mouse — a finger does not
   need a drawn cursor and a touch device would leave one stranded. */
.nx-stage.is-live { cursor: none; }
.nx-cursor {
    position: absolute;
    top: 0; left: 0;
    width: 34px; height: 34px;
    margin: -17px 0 0 -17px;
    border: 1px solid var(--accent);
    border-radius: 50%;
    pointer-events: none;
    opacity: 0;
    z-index: 3;
    transition: opacity .2s var(--ease), width .18s var(--ease), height .18s var(--ease);
}
.nx-cursor.is-on   { opacity: .85; }
.nx-cursor.is-down { width: 62px; height: 62px; margin: -31px 0 0 -31px; }
.nx-cursor::before {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 3px; height: 3px;
    margin: -1.5px 0 0 -1.5px;
    background: var(--accent);
    border-radius: 50%;
}
@media (hover: none) { .nx-cursor { display: none; } }

/* ------------------------------------------------------------------- HUD --
   One layer, four corners. `pointer-events: none` on the layer and `auto` on
   its children is what lets a click pass THROUGH the empty space between the
   panels and reach the cosmos. */
.nx-hud {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto 1fr auto;
    gap: 14px;
    padding: 14px;
}
.nx-hud > *, .nx-dock > * { pointer-events: auto; }

.nx-panel {
    background: var(--nx-hud-bg);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    border: 1px solid var(--nx-hud-line);
    border-radius: 3px;
}

/* ------------------------------------------------------------- the dock --
   The three collapsible panels are wrapped in one element that is NOT a box on
   a wide screen: `display: contents` drops it out of the layout entirely, so
   .nx-read, .nx-hints and .nx-ctrl remain direct participants in the HUD grid
   above and keep the corners they have always had. On a phone the same element
   becomes a real wrapping strip along the top — see the responsive block at the
   foot of this file — which is the only way three panels and a master switch
   fit a 375px screen without covering the cosmos they describe. */
.nx-dock { display: contents; }

/* ------------------------------------------------------ the fold headers --
   A panel's own switch. It is a <button> wearing a caption, so the whole strip
   is the target rather than a 10px chevron, and it is the caption that stays
   behind when the panel shuts: a closed panel has to say what is inside it or
   it is a chip nobody presses. */
.nx-fold {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; width: 100%;
    margin: 0 0 8px; padding: 0 0 6px;
    -webkit-appearance: none; appearance: none;
    background: none; border: 0; border-bottom: 1px solid var(--line-soft);
    border-radius: 0; text-align: left; cursor: pointer;
    font: inherit; font-size: 9px; font-weight: 500;
    letter-spacing: .18em; text-transform: uppercase;
    color: var(--ink-55);
    transition: color .18s var(--ease);
}
.nx-fold:hover { color: var(--accent); }
.nx-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.nx-fold__i {
    width: 10px; height: 10px; flex: 0 0 auto;
    transition: transform .2s var(--ease);
}
/* The two panels that are gapped grids space their own header. */
.nx-hints > .nx-fold, .nx-ctrl > .nx-fold { margin-bottom: 0; }
.nx-hints .nx-fold-b { display: grid; gap: 5px; }
.nx-ctrl  .nx-fold-b { display: grid; gap: 12px; }

/* Shut: the header is the whole panel, and it loses the rule under it — a
   hairline with nothing beneath it reads as a panel that failed to draw. */
.nx-panel.is-min > .nx-fold { margin: 0; padding: 0; border-bottom: 0; }
.nx-panel.is-min .nx-fold__i { transform: rotate(-90deg); }
.nx-panel.is-min .nx-fold-b { display: none; }
/* A chip is as wide as its caption. Both of these carry a min-width for the
   sake of their contents, and their contents are not on screen. The padding is
   stated here too, because the three panels are padded for what is inside them
   — 8px, 10px and 13px — and three chips of three different heights sitting in
   one strip read as three different controls. */
.nx-panel.is-min { min-width: 0; padding: 9px 12px; }

/* -------------------------------------------------------- the master switch
   Top left, the one corner of the HUD that was empty. It shuts all three at
   once; the panels keep their own switches for the times you want the dials
   and not the readout. */
.nx-all {
    grid-column: 1; grid-row: 1;
    justify-self: start; align-self: start;
    width: 30px; height: 30px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--nx-hud-bg);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    border: 1px solid var(--nx-hud-line);
    border-radius: 3px;
    color: var(--ink-55); cursor: pointer;
    transition: color .18s var(--ease), border-color .18s var(--ease);
}
.nx-all:hover { color: var(--accent); border-color: var(--accent); }
.nx-all:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nx-all__i { width: 13px; height: 13px; }
.nx-all__x { display: none; }
.nx-all.is-min .nx-all__c { display: none; }
.nx-all.is-min .nx-all__x { display: block; }

/* The readouts, top right. */
.nx-read {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    /* Right-aligned rather than stretched: the column is as wide as the widest
       thing in it, and a COLLAPSED readout stretched to the width of an open
       dial panel is a chip with 140px of empty glass beside its caption. */
    justify-self: end;
    padding: 10px 13px;
    min-width: 194px;
}
.nx-rows { display: grid; gap: 5px; margin: 0; }
.nx-row {
    display: flex;
    justify-content: space-between;
    gap: 22px;
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    line-height: 1.5;
}
.nx-row dt { color: var(--ink-55); }
.nx-row dd {
    margin: 0;
    color: var(--ink);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    /* Figures that change every frame must not move the label beside them. */
    font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}
.nx-read hr {
    border: 0;
    border-top: 1px solid var(--line-soft);
    margin: 2px 0;
}

/* ------------------------------------------------------------- the palettes
   Ten of them, and they live in the READOUT rather than in the controls for
   one reason: the controls panel is hidden below 900px and the readout is not.
   A palette you can only change on a desktop is a palette half the visitors
   never see.

   The strip is ten dots on one row — 10 x 15px plus nine 4px gaps is 186px,
   which is inside the panel's 194px floor, so choosing a colour costs no
   layout at all. */
.nx-pal {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--line-soft);
    display: grid;
    gap: 6px;
}
.nx-palcap {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-55);
}
.nx-palcap b { color: var(--accent); font-weight: 500; }
.nx-swatches {
    display: grid;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: 4px;
}
.nx-sw {
    aspect-ratio: 1;
    min-height: 15px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 50%;
    cursor: pointer;
    /* The swatch is painted in the palette it selects, in the edition being
       read — set inline by js/nexus.js, because a canvas palette is not a CSS
       token and there is nothing here that could know it. */
    background: var(--sw, transparent);
    transition: transform .15s var(--ease), box-shadow .15s var(--ease);
}
.nx-sw:hover { transform: scale(1.22); }
.nx-sw[aria-pressed="true"] {
    /* A ring rather than a border swap: the swatch has to keep its own colour
       at full size or the selected one is the one you can no longer identify. */
    box-shadow: 0 0 0 2px var(--nx-hud-bg), 0 0 0 3.4px var(--accent);
    border-color: transparent;
}
.nx-sw:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The hints, bottom left. */
.nx-hints {
    grid-column: 1;
    grid-row: 3;
    align-self: end;
    justify-self: start;
    display: grid;
    gap: 5px;
    font-size: 10px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--ink-55);
    padding: 10px 13px;
    max-width: 40ch;
}
.nx-hints b { color: var(--accent); font-weight: 500; }
.nx-hints .nx-line {
    text-transform: none;
    letter-spacing: 0;
    font-size: 12px;
    color: var(--ink-77);
    padding-top: 4px;
    border-top: 1px solid var(--line-soft);
    margin-top: 2px;
}
.nx-hints [hidden] { display: none; }

/* The controls, bottom right. */
.nx-ctrl {
    grid-column: 2;
    grid-row: 3;
    align-self: end;
    justify-self: end;
    padding: 13px;
    min-width: 232px;
    display: grid;
    gap: 12px;
}
.nx-field > .nx-cap {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    margin-bottom: 7px;
}
.nx-cap span:first-child { color: var(--ink-55); }
.nx-cap output {
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

/* -------------------------------------------------------------- sliders -- */
.nx-ctrl input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    width: 100%;
    height: 18px;              /* the TRACK is 2px; the target is 18 */
    background: transparent;
    cursor: ew-resize;
    margin: 0;
}
.nx-ctrl input[type="range"]::-webkit-slider-runnable-track {
    height: 2px;
    background: var(--line);
    border-radius: 2px;
}
.nx-ctrl input[type="range"]::-moz-range-track {
    height: 2px;
    background: var(--line);
    border-radius: 2px;
}
.nx-ctrl input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 13px; height: 13px;
    margin-top: -5.5px;
    background: var(--accent);
    border: 0;
    border-radius: 50%;
    transition: transform .15s var(--ease);
}
.nx-ctrl input[type="range"]::-moz-range-thumb {
    width: 13px; height: 13px;
    background: var(--accent);
    border: 0;
    border-radius: 50%;
}
.nx-ctrl input[type="range"]:hover::-webkit-slider-thumb { transform: scale(1.25); }
.nx-ctrl input[type="range"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* --------------------------------------------------------- action buttons */
.nx-acts { display: flex; gap: 7px; flex-wrap: wrap; }
.nx-act {
    width: 38px; height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 3px;
    color: var(--ink-55);
    cursor: pointer;
    padding: 0;
    transition: color .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease);
}
.nx-act svg { width: 14px; height: 14px; }
.nx-act:hover { color: var(--accent); border-color: var(--accent); }
.nx-act.is-on {
    color: var(--on-accent);
    background: var(--accent-fill);
    border-color: var(--accent-fill);
}
.nx-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------- full screen, in the bar --
   The same control as the HUD's corners button, sized to the navbar: the
   stage's full-screen mode was only reachable from inside the stage, which a
   phone that has scrolled past it never sees. Round because it sits beside
   the edition pill, and tokens only — the dark edition repoints them. */
.nav__fs {
    flex: 0 0 auto;
    width: 30px; height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 999px;
    color: var(--ink-55);
    cursor: pointer;
    padding: 0;
    transition: color .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease);
}
.nav__fs:hover { color: var(--accent); border-color: var(--accent); }
.nav__fs.is-on {
    color: var(--on-accent);
    background: var(--accent-fill);
    border-color: var(--accent-fill);
}
.nav__fs:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------- mode bar --
   Eight of them. On a wide screen that is one row; on a phone it is a 4x2
   grid, because eight buttons in a scrolling strip means four of them are
   permanently invisible. */
.nx-bar {
    grid-column: 1 / -1;
    grid-row: 3;
    justify-self: center;
    align-self: end;
    /* The eight are in the BODY now, so this is a plain box with a caption
       above them — see the fold rules further up. Shut, it is a chip reading
       the name of whichever engine is running. */
    display: block;
    padding: 4px 7px 5px;
}
.nx-bar > .nx-fold { margin: 0 0 4px; padding: 0 0 4px; }
.nx-bar.is-min { padding: 9px 12px; }
.nx-bar .nx-fold-b {
    display: grid;
    grid-auto-flow: column;
    gap: 3px;
}
.nx-mode {
    position: relative;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 2px;
    color: var(--ink-55);
    padding: 9px 15px;
    font: inherit;
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: .16em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
    transition: color .2s var(--ease), background .2s var(--ease);
}
.nx-mode:hover { color: var(--ink); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.nx-mode.is-on {
    color: var(--on-accent);
    background: var(--accent-fill);
}
.nx-mode:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nx-mode .nx-key {
    position: absolute;
    top: 2px; right: 4px;
    font-size: 8px;
    letter-spacing: 0;
    opacity: .55;
}

/* ----------------------------------------------------------------- intro --
   Sits over the stage until the pointer arrives. It is not a loading screen —
   the cosmos is already running behind it. */
.nx-intro {
    position: absolute;
    inset: 0;
    z-index: 4;
    display: grid;
    place-content: center;
    justify-items: center;
    text-align: center;
    padding: var(--gutter);
    background: color-mix(in srgb, var(--paper) 82%, transparent);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    transition: opacity .9s var(--ease), visibility .9s var(--ease);
}
html[data-dark] .nx-intro { background: color-mix(in srgb, #0C1116 78%, transparent); }
.nx-intro.is-gone { opacity: 0; visibility: hidden; pointer-events: none; }
.nx-intro h1 {
    margin: 0;
    font-size: clamp(56px, 13vw, 148px);
    font-weight: 500;
    letter-spacing: -.045em;
    line-height: .92;
    color: var(--ink);
}
.nx-intro p {
    margin: 14px 0 0;
    font-size: 10px;
    letter-spacing: .5em;
    text-transform: uppercase;
    color: var(--ink-55);
    padding-left: .5em;             /* letter-spacing hangs off the last glyph */
}
.nx-intro .nx-rule {
    width: 1px; height: 52px;
    background: linear-gradient(to bottom, transparent, var(--line), transparent);
    margin: 30px 0;
}
.nx-intro .nx-go {
    font-size: 10px;
    letter-spacing: .34em;
    text-transform: uppercase;
    color: var(--accent);
    padding-left: .34em;
}

/* The capture flash. */
.nx-flash {
    position: absolute;
    inset: 0;
    z-index: 5;
    background: var(--ink);
    opacity: 0;
    pointer-events: none;
    transition: opacity .32s var(--ease);
}
.nx-flash.is-on { opacity: .32; transition-duration: .05s; }

/* ================================================== THE WRITTEN SECTION == */
.nx-below { padding: var(--band) 0; }
.nx-below h2 {
    margin: 0 0 .5rem;
    font-size: clamp(28px, 4vw, 44px);
    font-weight: 500;
    letter-spacing: -.02em;
    color: var(--ink);
    line-height: 1.1;
}

.nx-cards {
    display: grid;
    /* minmax(0, …) and not 1fr: one long unbreakable word in a card sets the
       width of every other card in the row otherwise. */
    grid-template-columns: repeat(auto-fit, minmax(min(268px, 100%), 1fr));
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    margin-top: 2.4rem;
}
.nx-card {
    background: var(--paper);
    padding: 22px 22px 24px;
    display: grid;
    gap: 9px;
    align-content: start;
    text-align: left;
    border: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: background .2s var(--ease);
    min-width: 0;
}
html[data-dark] .nx-card { background: var(--deep-soft); }
.nx-card:hover { background: color-mix(in srgb, var(--accent) 7%, var(--paper)); }
html[data-dark] .nx-card:hover { background: color-mix(in srgb, var(--accent) 14%, var(--deep-soft)); }
.nx-card:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.nx-card .nx-n {
    font-size: 10px;
    letter-spacing: .2em;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}
.nx-card h3 {
    margin: 0;
    font-size: 15px;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ink);
}
.nx-card p { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--ink-77); }
.nx-card .nx-what {
    font-size: 12px;
    color: var(--ink-55);
    padding-top: 8px;
    border-top: 1px solid var(--line-soft);
}

.nx-keys {
    margin-top: 2.4rem;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
    gap: 10px 26px;
    font-size: 14px;
}
.nx-keys div { display: flex; gap: 11px; align-items: baseline; }
.nx-keys kbd {
    font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 11px;
    border: 1px solid var(--line);
    border-bottom-width: 2px;
    border-radius: 3px;
    padding: 2px 7px;
    color: var(--ink);
    background: var(--tint);
    flex: 0 0 auto;
}
html[data-dark] .nx-keys kbd { background: var(--deep-soft); }

/* ============================================================ RESPONSIVE ==
   Two things change on a phone and both matter.

   THE STAGE STOPS BEING THE WHOLE SCREEN. It is `touch-action: none`, which
   means a drag on it steers the field instead of scrolling the page — correct
   for the cosmos, and a trap if the stage fills the viewport, because there is
   then nowhere left to put a finger to get past it. At 62svh there is always
   page below it to scroll from.

   THE CONTROLS USED TO GO. `display: none` on .nx-ctrl and .nx-hints was the
   old answer to "three sliders stacked over a phone-sized cosmos leave no
   cosmos", and it was the wrong half of the trade: it took the dials off the
   phone entirely rather than getting them out of the way. They are now three
   CHIPS in one strip along the top — shut by default on a phone, one tap from
   open, and the cosmos keeps the screen. The dock is the element that makes
   that a layout change rather than a second copy of the markup.
   ========================================================================== */
@media (max-width: 900px) {
    .nx-dock {
        display: flex; flex-wrap: wrap; align-items: flex-start; gap: 9px;
        grid-column: 1 / -1; grid-row: 1; align-self: start;
        /* The dock is now a real box spanning the width of the stage. Without
           this, its empty half swallows every click meant for the cosmos. */
        pointer-events: none;
    }
    /* An open panel takes the strip's full width rather than squeezing in
       beside a chip: 232px of sliders and 194px of readout do not sit side by
       side on a 375px screen, and half a slider is not a slider. */
    .nx-panel:not(.is-min) { flex: 1 1 100%; }
    /* THE CORNERS ARE STILL DECLARED. .nx-hints and .nx-ctrl carry
       `align-self: end` for the grid they sit in on a wide screen, and in a
       flex row that word means "sit on the bottom of the line" — which
       staggered the three chips down the strip by the height difference
       between them. In this layout they all start at the top. */
    .nx-dock > * { align-self: flex-start; }
    .nx-read  { min-width: 0; padding: 8px 10px; }
    .nx-hints { max-width: none; }
    .nx-row   { gap: 14px; font-size: 9.5px; }
    .nx-mode  { padding: 10px 11px; font-size: 10px; letter-spacing: .1em; }
}

/* A PHONE HELD SIDEWAYS IS A FULL-SCREEN COSMOS. In landscape there is no
   reading to do — the written sections are unreachable from a stage that owns
   the drag anyway — so the stage takes the whole viewport, and the bar goes
   with the rest: 62px of a 375px-tall screen is a sixth of the cosmos spent on
   chrome nobody is reading sideways. Nothing is lost by it. The mode exists
   only while the phone is turned, and turning it back puts every one of them
   back where it was. `pointer: coarse` is the gate, so a small desktop window
   never trips it. */
@media (orientation: landscape) and (max-height: 560px) and (pointer: coarse) {
    .nav      { display: none; }
    .nx-stage { height: 100svh; min-height: 0; }
    .nx-hud   { padding: 7px; gap: 7px; }
    .nx-mode  { padding: 7px 9px; }
}
@media (max-width: 760px) {
    .nx-stage { height: 62svh; min-height: 380px; }
    .nx-hud   { padding: 9px; gap: 9px; }
    .nx-bar   { width: 100%; justify-self: stretch; }
    .nx-bar.is-min { width: auto; justify-self: center; }
    .nx-bar .nx-fold-b {
        grid-auto-flow: row;
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
    .nx-mode  { padding: 11px 4px; font-size: 9.5px; letter-spacing: .06em; }
    .nx-mode .nx-key { display: none; }
}
/* FOUR COLUMNS ALL THE WAY DOWN. Dropping to two below 380px looked like the
   careful thing and was the wrong one: eight buttons in two columns is four
   rows, which ate a hundred and seventy-seven pixels of a five-hundred-pixel
   stage — a third of the cosmos, spent on its own menu. FILAMENT is the widest
   label and measures about 52px set at this size; four columns of a 320px
   screen give each button 74. It fits, and the stage keeps its height. */
@media (max-width: 340px) {
    .nx-mode { font-size: 9px; letter-spacing: .02em; padding-inline: 2px; }
}

/* Someone who asked for less motion gets no transitions from us either. The
   cosmos itself starts paused; that is decided in js/nexus.js. */
@media (prefers-reduced-motion: reduce) {
    .nx-cursor, .nx-intro, .nx-flash, .nx-card, .nx-act, .nx-mode { transition: none; }
}
