/* ============================================================
   FIELD TRANSFER CONSOLE — shared presentation. Used by the
   homepage (inside the fc-overlay) and by the unlisted bench
   at field-station-c9e2a7.html. Requires fonts.css/style.css
   tokens (--mono, --serif). All geometry hangs off --cell.
   ============================================================ */
    :root {
      --bay: #050505;
      /* two phosphor voices: the warm print and the cool readout */
      --warm: #ead4a8;
      --warm-dim: rgba(234, 212, 168, 0.4);
      --cool: #dde2da;
      --cool-dim: rgba(221, 226, 218, 0.55);
      --print: var(--warm);
      --print-dim: var(--warm-dim);
      --hairline: rgba(216, 206, 186, 0.34);
      --teal-off: #071314;   /* off is OFF: pigment in the dark */
      --red-off:  #150507;
    }
    /* ── the console exists only from the transfer onward ── */
    .fs-console-el { display: none; }
    body[data-fs="console"] .fs-console-el { display: block; }

    /* ============================================================
       CHASSIS: the housing. Sized from one number - the console
       width - from which the cell derives. 20 cells + 19 gaps
       across; gap = cell/3.
       ============================================================ */
    /* ── the physical model (from the section drawing): a simple
       PLASTIC FRAME - thin on top and sides, thick at the bottom
       where its inner face SLANTS up to meet the glass - holding
       ONE FLAT GLASS PANEL. The screens are masked windows UNDER
       the glass; only the tile and the two buttons sit PROUD of
       it. Four type sizes serve the whole instrument. ── */
    .fs-chassis {
      --w: min(660px, 92vw, 74svh);
      --cell: calc(var(--w) / 26.3333);
      --g: calc(var(--cell) / 3);
      --fs-small:  calc(var(--cell) * 0.32);
      --fs-medium: calc(var(--cell) * 0.42);
      --fs-normal: calc(var(--cell) * 0.6);
      --fs-big:    calc(var(--cell) * 0.92);
      box-sizing: border-box;
      padding: calc(var(--cell) * 0.5);
      padding-bottom: 0;
      border-radius: calc(var(--cell) * 0.3);
      background: linear-gradient(180deg, #28282c 0%, #1c1c20 5%, #1c1c20 100%);
      border: 1px solid #000;
      box-shadow:
        0 calc(var(--cell) * 0.6) calc(var(--cell) * 1.6) rgba(0, 0, 0, 0.78),
        0 1px 0 rgba(255, 255, 255, 0.05),
        inset 0 2px 1px rgba(255, 255, 255, 0.14),
        inset 2px 0 2px rgba(255, 255, 255, 0.05),
        inset -2px 0 3px rgba(0, 0, 0, 0.6);
    }
    /* the glass: one dark pane, slightly sunk behind the frame's
       lip (the lip shades its top and sides), one long reflection
       across the whole face */
    .fs-glass {
      position: relative;
      box-sizing: border-box;
      padding: calc(var(--cell) * 0.6);
      background: linear-gradient(168deg, #121316 0%, #0b0c0e 45%, #070809 100%);
      border: 1px solid #000;
      border-bottom: 0;
      border-radius: 2px 2px 0 0;
      box-shadow:
        inset 0 calc(var(--cell) * 0.12) calc(var(--cell) * 0.25) rgba(0, 0, 0, 0.85),
        inset calc(var(--cell) * 0.08) 0 calc(var(--cell) * 0.2) rgba(0, 0, 0, 0.6),
        inset calc(var(--cell) * -0.08) 0 calc(var(--cell) * 0.2) rgba(0, 0, 0, 0.6);
    }
    /* the sheen lies ON the glass - over the masked screens,
       never over the protruding parts (they carry z-index 2) */
    .fs-glass::after {
      content: '';
      position: absolute;
      inset: 0;
      z-index: 1;
      background:
        linear-gradient(112deg,
          rgba(255, 255, 255, 0) 30%,
          rgba(255, 255, 255, 0.028) 44%,
          rgba(255, 255, 255, 0.05) 50%,
          rgba(255, 255, 255, 0.02) 56%,
          rgba(255, 255, 255, 0) 68%);
      pointer-events: none;
    }
    /* the slanted sill: the thick lower frame's inner reveal. It
       starts flush at the glass's bottom edge, a FLAT surface a
       shade lighter than the frame face (it catches the overhead
       light), with only a thin contact shadow where it meets the
       glass, and lands crisply on the frame's front face. */
    .fs-sill {
      position: relative;
      height: calc(var(--cell) * 0.38);
      margin: 0 calc(var(--cell) * -0.5);
      /* measured from the model: a SHORT ramp (about a fifth of
         the face height - the slope tilts away and foreshortens)
         rising from the glass value to EXACTLY the face value.
         No edge line: it simply arrives at the face. */
      background: linear-gradient(180deg,
        #0a0a0c 0%, #111115 35%, #1c1c20 86%, #33333a 99%, #3c3c44 100%);
      clip-path: polygon(0% 100%, calc(var(--cell) * 0.5) 0%, calc(100% - var(--cell) * 0.5) 0%, 100% 100%);
      /* the extruded lip: a bright catch along the corner, a thin
         shadow right under it where the face turns away */
      box-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
    }
    /* the corners the trapezoid cuts away reveal the frame: they
       read as the reveal's side walls */
    .fs-grid {
      display: grid;
      grid-template-columns: repeat(20, var(--cell));
      grid-auto-rows: var(--cell);
      gap: var(--g);
    }
    /* the maker's plate: engraved in the lower bezel */
    .fs-plate {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: calc(var(--cell) * 0.7) calc(var(--cell) * 0.35) calc(var(--cell) * 0.85);
      /* the maker's mark: a sixties corporate wordmark - bold,
         wide, cool grey, printed on the plastic */
      font-family: var(--serif);
      font-weight: 700;
      font-size: var(--fs-small);
      letter-spacing: 0.34em;
      text-transform: uppercase;
      color: #5b6068;
      text-shadow: 0 1px 0 rgba(255, 255, 255, 0.06);
    }
    .fs-plate span:last-child { letter-spacing: 0.24em; }

    /* ── the masked windows: flat areas UNDER the glass. No
       recess, no volume - a printed hairline marks the opening
       in the mask, the display phosphor glows behind it. ── */
    .screen {
      position: relative;
      box-sizing: border-box;
      background: #030507;
      border: 1px solid var(--hairline);
      border-radius: 2px;
      overflow: hidden;
    }

    /* ============================================================
       1 · STATUS TILE — cream backlit plexi, 4x4 cells (the unit
       square). Lit always; blinks softly while a procedure runs.
       ============================================================ */
    .fs-tile {
      position: relative;
      z-index: 2;                    /* proud of the glass */
      grid-column: 1 / 5;
      grid-row: 1 / 5;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      text-align: left;
      padding: calc(var(--cell) * 0.42) calc(var(--cell) * 0.38);
      border-radius: 2px;
      border: 1px solid rgba(0, 0, 0, 0.85);
      background:
        radial-gradient(130% 100% at 50% 30%, #f4e7cd 0%, #e7d6b5 52%, #cbb894 100%);
      box-shadow:
        inset 0 0 calc(var(--cell) * 1) rgba(116, 92, 54, 0.4),
        inset 0 1px 0 rgba(255, 255, 255, 0.55),
        inset 0 -2px calc(var(--cell) * 0.2) rgba(90, 70, 40, 0.35),
        0 2px 0 rgba(0, 0, 0, 0.9),
        0 calc(var(--cell) * 0.18) calc(var(--cell) * 0.4) rgba(0, 0, 0, 0.65),
        0 0 calc(var(--cell) * 0.8) rgba(238, 220, 185, 0.12);
      color: #292215;
    }
    .fs-tile-main {
      font-family: var(--mono);
      font-weight: 600;
      font-size: var(--fs-normal);
      line-height: 1.28;
      letter-spacing: 0.04em;
      text-transform: uppercase;
    }
    .fs-tile-cap {
      font-family: var(--mono);
      font-size: var(--fs-small);
      letter-spacing: 0.28em;
      text-transform: uppercase;
      opacity: 0.72;
    }
    body[data-mon="on"] .fs-tile { animation: fs-tile-blink 1.3s ease-in-out infinite; }
    @keyframes fs-tile-blink {
      0%, 100% { filter: brightness(1); }
      50%      { filter: brightness(0.62); }
    }

    /* ============================================================
       2 · SCOPE — the life-functions monitor. Canvas trace between
       two label columns; the right column is live (DATA VIS AUD
       NAV light with the systems they name).
       ============================================================ */
    .fs-scope-mod {
      grid-column: 5 / 21;
      grid-row: 1 / 5;
      display: flex;
      align-items: stretch;
    }
    .fs-scope-side {
      flex: 0 0 calc(var(--cell) * 1.9);
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      box-sizing: border-box;
      padding: calc(var(--cell) * 0.32) 0;
      font-family: var(--mono);
      font-size: var(--fs-small);
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: var(--cool-dim);            /* the cool readout voice */
    }
    .fs-scope-side.left  { align-items: flex-start; padding-left: calc(var(--cell) * 0.35); border-right: 1px solid rgba(216, 206, 186, 0.12); }
    .fs-scope-side.right { align-items: flex-start; padding-left: calc(var(--cell) * 0.4);  border-left:  1px solid rgba(216, 206, 186, 0.12); }
    .fs-scope-side .sep { opacity: 0.5; }
    .fs-scope-side .lit {
      color: var(--cool);
      text-shadow: 0 0 calc(var(--cell) * 0.22) rgba(221, 226, 218, 0.7);
    }
    #fs-scope { flex: 1; min-width: 0; height: 100%; display: block; }

    /* ============================================================
       3 · MESSAGE DISPLAY — the system speaks here, typed, with a
       block cursor. The commands never change their word again.
       ============================================================ */
    .fs-display {
      grid-column: 1 / 21;
      grid-row: 5 / 10;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: calc(var(--cell) * 0.5) calc(var(--cell) * 1.1);
      text-align: center;
    }
    .fs-msg {
      margin: 0;
      font-family: var(--mono);
      font-size: var(--fs-big);
      line-height: 1.5;
      color: var(--warm);
      text-shadow: 0 0 calc(var(--cell) * 0.35) rgba(234, 212, 168, 0.5);
      text-wrap: balance;
    }
    .fs-msg .dim { color: var(--print-dim); text-shadow: none; }
    .fs-cursor {
      display: inline-block;
      width: 0.55ch;
      height: 1em;
      margin-left: 0.25ch;
      vertical-align: text-bottom;
      background: var(--print);
      box-shadow: 0 0 calc(var(--cell) * 0.25) rgba(232, 214, 178, 0.6);
      animation: fs-cursor 1.1s steps(2, jump-none) infinite;
    }
    /* while receiving, the block cursor IS the next character's
       cell: no layout ever moves. The resting cursor element
       leaves the line entirely. */
    .fs-cursor.typing { display: none; }
    .fs-msg span.cell {
      visibility: visible !important;
      color: transparent;
      background: var(--print);
      box-shadow: 0 0 calc(var(--cell) * 0.25) rgba(232, 214, 178, 0.6);
    }
    @keyframes fs-cursor { 0% { opacity: 1; } 100% { opacity: 0; } }

    /* ============================================================
       4 · COMMANDS — backlit plexi. The pigmented plastic is
       always there; a lamp layer (::before) behind it goes on and
       off. INTERACT breathes softly whenever it wants a hand.
       ============================================================ */
    .fs-cmd {
      position: relative;
      z-index: 2;                    /* proud of the glass */
      grid-column: 1 / 21;
      display: flex;
      align-items: center;
      justify-content: center;
      box-sizing: border-box;
      border: 1px solid rgba(0, 0, 0, 0.9);
      border-radius: 3px;
      padding: 0;
      cursor: pointer;
      /* the slab: a hard bottom edge face and a cast shadow
         falling on the glass beneath */
      box-shadow:
        0 2px 0 rgba(0, 0, 0, 0.9),
        0 calc(var(--cell) * 0.18) calc(var(--cell) * 0.45) rgba(0, 0, 0, 0.65);
      transition: box-shadow 0.3s ease;
    }
    .cmd-interact { grid-row: 10 / 13; background: var(--teal-off); }
    .cmd-exit     { grid-row: 13 / 16; background: var(--red-off); }
    /* the lamp: a REAL element, not a pseudo - WebKit is unreliable
       at (re)starting animations on pseudo-elements when a state
       selector flips, which is why visionOS showed the button
       frozen at full. The lamp's animation NEVER stops; disabling
       the button merely hides it (visibility keeps it running). */
    .fs-lamp {
      position: absolute;
      inset: 0;
      border-radius: 2px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-style: normal;
      opacity: 1;
      pointer-events: none;
    }
    .fs-cmd:disabled .fs-lamp { visibility: hidden; }
    .cmd-interact .fs-lamp {
      background:
        radial-gradient(100% 260% at 50% 45%,
          #58d6cd 0%, #3fc2bb 45%, #2b9f9a 74%, #197073 90%, #0f5254 100%);
      animation: fs-lamp 2.6s ease-in-out infinite;
    }
    .cmd-interact[data-mode="armed"] .fs-lamp { animation-duration: 1.5s; }
    .cmd-exit .fs-lamp {
      /* a register below INTERACT: present, not competing */
      background:
        radial-gradient(100% 260% at 50% 45%,
          #b93a46 0%, #9c2733 45%, #771a24 74%, #4e1018 90%, #380b11 100%);
    }
    /* the plexi face: a thin top sheen and a firm edge vignette -
       always there, lit or not */
    .fs-cmd::after {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: inherit;
      pointer-events: none;
      box-shadow:
        inset 0 0 calc(var(--cell) * 0.42) rgba(0, 0, 0, 0.5),
        inset 0 2px 1px rgba(255, 255, 255, 0.28),
        inset 0 -2px calc(var(--cell) * 0.16) rgba(0, 0, 0, 0.55);
    }
    /* two copies of the word: a dim GHOST printed on the dark
       plastic (all the disabled state shows), and the LIT label
       living inside the lamp, riding its light exactly */
    .fs-ghost, .fs-lamp b {
      font-family: var(--serif);
      font-weight: 700;
      font-size: var(--fs-big);
      letter-spacing: 0.14em;
      text-indent: 0.14em;
      text-transform: uppercase;
    }
    .fs-ghost {
      position: relative;
      color: rgba(225, 235, 230, 0.09);
    }
    .fs-lamp b {
      color: #f6f1e4;
      text-shadow:
        0 0 calc(var(--cell) * 0.12) rgba(255, 252, 240, 0.9),
        0 0 calc(var(--cell) * 0.45) rgba(255, 252, 240, 0.4),
        0 1px 2px rgba(0, 0, 0, 0.35);
    }
    .cmd-interact:not(:disabled) {
      box-shadow:
        0 2px 0 rgba(0, 0, 0, 0.9),
        0 calc(var(--cell) * 0.18) calc(var(--cell) * 0.45) rgba(0, 0, 0, 0.65),
        0 0 calc(var(--cell) * 1.2) rgba(60, 190, 182, 0.35);
    }
    .cmd-exit:not(:disabled) {
      box-shadow:
        0 2px 0 rgba(0, 0, 0, 0.9),
        0 calc(var(--cell) * 0.18) calc(var(--cell) * 0.45) rgba(0, 0, 0, 0.65),
        0 0 calc(var(--cell) * 1.2) rgba(200, 55, 68, 0.2);
    }
    /* the blink: lamp and label together, a filament that never
       goes cold. It runs permanently - visibility gates it. */
    @keyframes fs-lamp {
      0%, 100% { opacity: 0.32; }
      50%      { opacity: 1; }
    }
    /* On visionOS the GAZE highlight is the system's own glass -
       Safari ignores page hover rules there, so these apply only
       where a real pointer hovers (desktop, the pane) */
    @media (hover: hover) {
      .fs-cmd:not(:disabled):hover .fs-lamp,
      .fs-cmd:not(:disabled):focus-visible .fs-lamp {
        animation-play-state: paused;
        filter: brightness(1.2);
      }
      .fs-cmd:not(:disabled):hover::after,
      .fs-cmd:not(:disabled):focus-visible::after {
        background: radial-gradient(95% 220% at 50% 45%,
          rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0.08) 55%, transparent 80%);
      }
    }
    .fs-cmd:focus-visible { outline: none; }
    .fs-cmd:not(:disabled):active { transform: translateY(1px); }
    .fs-cmd:not(:disabled):active .fs-lamp { filter: brightness(1.3); }
    .fs-cmd:disabled { cursor: default; }

    /* ============================================================
       5 · DIAGNOSTICS — the station feed, flowing through three
       terminal columns like a printout.
       ============================================================ */
    .fs-diag {
      grid-column: 1 / 21;
      grid-row: 16 / 22;
      display: flex;
      flex-direction: column;
      padding: calc(var(--cell) * 0.35) calc(var(--cell) * 0.45);
      text-align: left;
    }
    .fs-diag-head {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
      padding-bottom: calc(var(--cell) * 0.24);
      margin-bottom: calc(var(--cell) * 0.26);
      border-bottom: 1px solid rgba(232, 220, 190, 0.45);
      font-family: var(--mono);
      font-size: var(--fs-medium);
      letter-spacing: 0.2em;
      text-transform: uppercase;
      color: var(--warm);
      text-shadow: 0 0 10px rgba(234, 212, 168, 0.5);
    }
    .fs-log {
      flex: 1;
      min-height: 0;
      --lgap: calc(var(--cell) * 0.7);
      column-count: 3;
      column-gap: var(--lgap);
      /* the rules are printed on the screen, not drawn by the
         text: they stand whether the columns are full or empty */
      background:
        linear-gradient(rgba(232, 220, 190, 0.15), rgba(232, 220, 190, 0.15))
          no-repeat calc(33.333% - var(--lgap) / 6) 0 / 1px 100%,
        linear-gradient(rgba(232, 220, 190, 0.15), rgba(232, 220, 190, 0.15))
          no-repeat calc(66.667% + var(--lgap) / 6) 0 / 1px 100%;
      column-fill: auto;
      overflow: hidden;
      font-family: var(--mono);
      font-size: var(--fs-small);
      line-height: 1.7;
      color: rgba(234, 212, 168, 0.9);
      text-shadow: 0 0 7px rgba(234, 212, 168, 0.4);
      pointer-events: none;
    }
    .fs-log div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

    @media (prefers-reduced-motion: reduce) {
      body[data-mon="on"] .fs-tile,
      .cmd-interact .fs-lamp,
      .fs-cursor { animation: none; }
    }

    /* ── the dock holder: rendered but unseen (0908-E). It only
       needs to EXIST while the console runs - on the homepage it
       would otherwise sit as a small black box in the corner ── */
    .fs-bay {
      display: none;
      position: fixed;
      right: 10px;
      bottom: 10px;
      width: 34px;
      background: #000;
      border-radius: 2px;
      overflow: hidden;
      opacity: 0.9;
    }
    body[data-fs="console"] .fs-bay { display: block; }
    #fs-video {
      display: block;
      width: 30px;
      aspect-ratio: 4 / 9;
      margin: 2px auto;
      background: #000;
    }
    .fs-shutter {
      position: absolute;
      inset: 0;
      background: #000;
      pointer-events: none;
    }

/* ============================================================
   THE OVERLAY (homepage only): pressing 'Enter immersive' opens
   a black Bureau sheet - the preparing line in the house serif -
   then the console rises out of the dark.
   ============================================================ */
.fc-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  box-sizing: border-box;
  background: #050505;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.7s ease, visibility 0s linear 0.7s;
}
.fc-overlay.open {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.7s ease;
}
.fc-inter {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  margin: 0;
  font-family: var(--serif, Georgia, serif);
  font-style: italic;
  font-size: clamp(1.05rem, 2.6vw, 1.45rem);
  line-height: 1.7;
  color: var(--mid-p, #8a8578);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 1.1s ease 0.25s, transform 1.1s ease 0.25s;
  pointer-events: none;
}
.fc-inter span { display: block; max-width: 36em; }
.fc-inter em { white-space: nowrap; }
.fc-overlay.open .fc-inter { opacity: 1; transform: none; }
.fc-overlay.reveal .fc-inter {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.fc-console {
  display: flex;
  justify-content: center;
  width: 100%;
  opacity: 0;
  transform: translateY(28px) scale(0.985);
  pointer-events: none;              /* invisible must be untouchable */
  transition: opacity 1.1s ease 0.35s, transform 1.1s cubic-bezier(0.16, 1, 0.3, 1) 0.35s;
}
.fc-overlay.reveal .fc-console { opacity: 1; transform: none; pointer-events: auto; }
html.fc-open, html.fc-open body { overflow: hidden; }
