/* ==========================================================================
   Node 42 — FQ 00 directory grid + the panel's frequency readout / stepper
   Spec from Vel, 2026-09-01.
   ========================================================================== */

/* ---- panel: frequency readout ------------------------------------------ *
   Vel asked for "a black (invisible) box that shows the CURRENT frequency
   number". No fill and no border: it sits straight on the panel art's own black
   interior, so only the digits read. */
.n42-readout {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: #000;
    border: 0;
    padding: 0.1em 0 0.25em;
    flex: 0 0 auto;
}

/* An <input> styled to look like a readout, not a form field: the box stays
   "invisible" as specified, and the digits are the only thing that reads.
   SPECIFICITY IS DELIBERATE AND MEASURED. Astra ships
   `.astra-dark-mode-enable input[type=text]` at (0,2,1). `.n42-readout
   input.n42-readout-num` is ALSO (0,2,1) — a tie, broken by source order, which for a
   plugin sheet against a theme sheet is luck rather than design, and it lost. The
   digits sampled pure rgb(255,255,255) from a screenshot while the labels beside them
   sampled the accent green, which proved the variable was fine and the cascade was
   not. The full ancestor chain below is (0,4,1) and wins outright — no !important,
   and no dependence on which stylesheet happens to print last. */
.n42 .n42-panel .n42-readout input.n42-readout-num {
    font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
    font-size: 2.4em;
    font-weight: 700;
    line-height: 1;
    /* !important IS EARNED HERE, and the evidence is specific. The site carries an
       inline <style> block of BuddyPress form fixes with
       `color:#ffffff !important` (and `-webkit-text-fill-color`) on text inputs.
       No selector can outrank !important, so matching it is the only correct move.
       How I know it is the colour and not my whole rule losing: the blue text-shadow
       below WAS rendering while the digits sampled pure white — same declaration
       block, one property overridden. A rule that partly applies is the tell.
       -webkit-text-fill-color must be set too: in Chrome it overrides `color`
       outright, so setting colour alone would have left this still white. */
    color: var(--n42-accent) !important;
    -webkit-text-fill-color: var(--n42-accent) !important;
    letter-spacing: 0.06em;
    text-shadow: 0 0 10px rgba(80, 160, 255, 0.75);

    width: 2.4em;
    text-align: center;
    background: transparent;
    border: 0;
    border-bottom: 1px solid transparent;   /* reserved, so focus adds no layout shift */
    padding: 0;
    margin: 0;
    -moz-appearance: textfield;
    appearance: textfield;
    caret-color: var(--n42-accent);
}

.n42-readout-num::-webkit-outer-spin-button,
.n42-readout-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* It has to be discoverable as typeable without looking like a form control until
   you touch it. */
.n42 .n42-panel .n42-readout input.n42-readout-num:hover { border-bottom-color: rgba(90, 150, 255, 0.45); }
.n42 .n42-panel .n42-readout input.n42-readout-num:focus {
    outline: none;
    border-bottom-color: var(--n42-accent);
    background: rgba(10, 30, 70, 0.45);
}

/* A refused frequency snaps back and says so, briefly. Silence would read as the
   keystroke not registering. */
.n42 .n42-panel .n42-readout input.n42-readout-num.is-rejected {
    color: #ff6b52 !important;
    -webkit-text-fill-color: #ff6b52 !important;
    text-shadow: 0 0 10px rgba(255, 90, 60, 0.8);
    border-bottom-color: #ff6b52;
}

.n42-readout-name {
    font-size: 0.78em;
    color: #8fb4e8;
    opacity: 0.85;
    text-align: center;
    line-height: 1.15;
    margin-top: 0.2em;
}

/* ---- panel: the up/down stepper ---------------------------------------- */
.n42-stepper {
    display: flex;
    /* SIDE BY SIDE, not stacked (Vel, 2026-09-13): "they usually appear side by side on human
       remote control devices for tv's and such, so this is the configuration people generally
       expect." The control is a channel rocker, and every physical one a person has held since
       about 1980 has been horizontal. Matching that costs one property and removes a small
       moment of "which way is up" from a control nobody should have to think about. */
    flex-direction: row;
    gap: 0.3em;
    flex: 0 0 auto;
}

.n42-step {
    font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
    /* Smaller now that they sit in a row: two buttons share the panel's width, and the panel is
       a narrow strip (--n42-panel-ratio 0.3481). flex:1 1 0 rather than width:100% so they split
       the space evenly instead of each demanding all of it and wrapping back into a column --
       which would have quietly restored the stacked layout at narrow widths. */
    font-size: 0.95em;
    font-weight: 700;
    line-height: 1;
    padding: 0.2em 0;
    flex: 1 1 0;
    min-width: 0;
    background: rgba(10, 30, 70, 0.55);
    border: 1px solid rgba(90, 150, 255, 0.35);
    border-radius: 3px;
    color: #cfe3ff;
    cursor: pointer;
}
.n42-step:hover { background: rgba(20, 60, 130, 0.8); border-color: rgba(140, 190, 255, 0.75); }
.n42-step:active { background: rgba(40, 110, 210, 0.95); }
.n42-step:focus-visible { outline: 2px solid var(--n42-accent); outline-offset: 1px; }

/* ==========================================================================
   FQ 00 — the directory grid
   ==========================================================================
   Vel: "A blue screen with white divider lines. Left side, each box should
   contain a FQ # with what the FQ shows... then timeslots (times are always
   present across the top, like a stationary row in a spreadsheet)."

   The label column width is a custom property because BOTH the header corner and
   every row label depend on it, and the "now" marker has to be offset by exactly
   the same amount. One value, three consumers — a second copy would drift. */
.n42-guide {
    --n42-guide-label-w: 30%;
    --n42-guide-rule: rgba(255, 255, 255, 0.85);

    position: absolute;
    /* NOT inset:0. The aperture is a rectangle but the bezel's INNER corners are
       rounded, and the frame image sits above this at a higher z-index — so a guide
       flush to the aperture has its corners covered. First render clipped the corner
       label to "REQUENCY". Inset past the corner radius (~40px of a 1550px-wide
       aperture) and the whole grid clears the bezel. */
    inset: 3.5% 2.5%;
    border-radius: 4px;
    background: #0a2a6e;            /* the blue screen */
    color: #fff;
    display: flex;
    flex-direction: column;
    font-size: clamp(0.5rem, 1.05vw, 0.95rem);
    line-height: 1.2;
    overflow: hidden;
    z-index: 1;
}
.n42-guide[hidden] { display: none; }

/* The stationary header row — "like a stationary row in a spreadsheet". */
.n42-guide-head {
    display: flex;
    flex: 0 0 auto;
    border-bottom: 2px solid var(--n42-guide-rule);
    background: #06184a;
    position: sticky;
    top: 0;
    z-index: 2;
}

.n42-guide-corner {
    flex: 0 0 var(--n42-guide-label-w);
    border-right: 2px solid var(--n42-guide-rule);
    padding: 0.35em 0.5em;
    font-size: 0.8em;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    opacity: 0.8;
}

.n42-guide-times { position: relative; flex: 1 1 auto; }

/* Absolutely positioned at its true fraction of the window, so a label always sits
   over the gridline it names rather than over an evenly-divided guess. */
.n42-guide-time {
    position: absolute;
    top: 0.35em;
    /* Sits just RIGHT of its gridline. A negative shift centred the label on the line,
       which pushed the leftmost one (at 0%) back over the label column's divider. */
    padding-left: 4px;
    font-size: 0.8em;
    white-space: nowrap;
    opacity: 0.9;
}

.n42-guide-body { flex: 1 1 auto; overflow-y: auto; }

.n42-guide-row {
    display: flex;
    border-bottom: 1px solid var(--n42-guide-rule);
    min-height: 2.4em;
}
.n42-guide-row:last-child { border-bottom: 0; }

.n42-guide-label {
    flex: 0 0 var(--n42-guide-label-w);
    border-right: 2px solid var(--n42-guide-rule);
    padding: 0.3em 0.5em;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.05em;
    min-width: 0;
}

.n42-guide-code {
    font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
    font-weight: 700;
    letter-spacing: 0.06em;
}

.n42-guide-name {
    font-size: 0.82em;
    opacity: 0.75;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.n42-guide-lane { position: relative; flex: 1 1 auto; min-width: 0; }

/* Vertical slot gridlines, drawn per lane so they align with the header labels. */
.n42-guide-rule {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: rgba(255, 255, 255, 0.28);
}

.n42-guide-prog {
    position: absolute;
    top: 3px;
    bottom: 3px;
    background: rgba(20, 70, 160, 0.92);
    border: 1px solid rgba(255, 255, 255, 0.55);
    border-radius: 2px;
    padding: 0 0.4em;
    display: flex;
    align-items: center;
    overflow: hidden;
    box-sizing: border-box;
}

.n42-guide-prog span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.86em;
}

.n42-guide-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    padding-left: 0.6em;
    font-size: 0.8em;
    opacity: 0.45;
    font-style: italic;
}

/* The "now" line, offset past the label column by the same custom property the
   labels use, so it cannot drift out of alignment with them. */
.n42-guide-now {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: #ff5a3c;
    box-shadow: 0 0 6px rgba(255, 90, 60, 0.9);
    z-index: 3;
    pointer-events: none;
}

@media (max-width: 700px) {
    .n42-guide { --n42-guide-label-w: 38%; font-size: 0.6rem; }
}
