/* skeuo-flash.css: instrument skin for this surface only. Unlayered, loaded after skeuo-a.css. Hex literals only in :root. */

/* ==========================================================================
   The flashing surface, dressed as bench hardware.

   The reader is holding a board when they use this, so the one control that
   matters is built to be found and pressed: a brushed console screwed onto the
   panel, a recessed glass window that says what is happening, a lamp beside it
   that agrees in colour, and one key with real travel.

   Nothing here paints running text. The steps, the notes and the lists keep
   the flat surfaces flash.css gives them.
   ========================================================================== */

:root {
  /* The three lamp states that are not the brand cyan. Amber is the same warm
     value the safety rule uses; the other two are the reading colours the
     device itself uses for a good and a low number. */
  --fl-lamp-wait: #d9a441;
  --fl-lamp-good: #35d07f;
  --fl-lamp-bad:  #ff5470;
}

/* The section panel: one machined plate, lit from the top left like every
   other surface on the site. */
.flash-panel {
  background-image: var(--sk-panel-face);
  background-color: var(--sk-metal);
  border-color: transparent;
  border-top-color: var(--color-accent);
  box-shadow: var(--sk-bevel), var(--sk-lift);
}

/* --------------------------------------------------------------------------
   The console

   A darker plate bolted onto the panel above. Its own grain runs the same way
   as everything else, and the four fixings are real background layers rather
   than borders, so they survive a resize.
   -------------------------------------------------------------------------- */
.flash-console {
  margin-top: var(--step-7);
  padding: clamp(var(--step-5), 3vw, var(--step-6));
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-card);
  border-top-width: 1px;
  background-image: var(--sk-brush), var(--sk-plate-face);
  background-color: var(--sk-metal-lo);
  box-shadow: var(--sk-bevel), var(--sk-lift);
}

.flash-screw {
  background-image: var(--sk-screw);
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

.flash-screw-tr,
.flash-screw-bl { background-image: var(--sk-screw-b); }

/* The lamp legend and the sub-headings are stamped rather than printed. */
.flash-console .flash-sub,
.flash-lamp-label,
.flash-ack-state {
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
}

/* --------------------------------------------------------------------------
   The status window

   Glass sunk into the plate. Near-black, one raking highlight, and a scanline
   period fine enough to read as a coating rather than as a CRT. It holds one
   short line, never a paragraph.
   -------------------------------------------------------------------------- */
.flash-glass {
  position: relative;
  overflow: hidden;
  background-color: var(--sk-glass);
  background-image:
    repeating-linear-gradient(180deg,
      transparent 0 3px, var(--sk-scanline) 3px 4px),
    linear-gradient(157deg, var(--sk-glass-lit) 0, transparent 42%);
  border: 1px solid rgba(0, 0, 0, 0.8);
  box-shadow: var(--sk-recess);
}

.flash-glass-text {
  color: var(--color-accent);
  text-shadow:
    0 0 6px color-mix(in srgb, var(--color-accent) 70%, transparent),
    0 0 18px color-mix(in srgb, var(--color-accent) 30%, transparent);
}

/* A written percentage fills the window's own bar. No numeric value, no bar. */
.flash-console[style*="--flash-pct"] .flash-glass::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: var(--flash-pct, 0%);
  background: var(--color-accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--color-accent) 60%, transparent);
}

/* --------------------------------------------------------------------------
   The lamp

   One dot in a countersunk socket. Its colour and the word beside it are set
   from the same attribute, so neither can drift from the other.
   -------------------------------------------------------------------------- */
.flash-lamp-dot {
  --fl-lamp: var(--fl-lamp-wait);
  background: radial-gradient(circle at 34% 30%,
    color-mix(in srgb, var(--fl-lamp) 45%, var(--sk-white)) 0 22%,
    var(--fl-lamp) 56%,
    color-mix(in srgb, var(--fl-lamp) 50%, var(--sk-black)) 100%);
  box-shadow:
    0 0 8px var(--fl-lamp),
    0 0 18px color-mix(in srgb, var(--fl-lamp) 45%, transparent),
    0 0 0 2px rgba(0, 0, 0, 0.8),
    0 0 0 3px var(--sk-edge-lit-2),
    inset 0 -1px 2px rgba(0, 0, 0, 0.55);
}

.flash-console[data-phase="writing"] .flash-lamp-dot,
.flash-console[data-phase="busy"] .flash-lamp-dot { --fl-lamp: var(--color-accent); }

.flash-console[data-phase="finished"] .flash-lamp-dot { --fl-lamp: var(--fl-lamp-good); }

.flash-console[data-phase="error"] .flash-lamp-dot { --fl-lamp: var(--fl-lamp-bad); }

/* An unavailable console has a dead lamp in a live socket. */
.flash-console[data-phase="unsupported"] .flash-lamp-dot {
  background: radial-gradient(circle at 34% 30%,
    var(--sk-metal-lo) 0 40%, var(--sk-lamp-dead) 100%);
  box-shadow:
    inset 0 2px 3px rgba(0, 0, 0, 0.9),
    0 0 0 2px rgba(0, 0, 0, 0.8),
    0 0 0 3px var(--sk-edge-lit-2);
}

/* The lamp breathes while it is writing, and only then, and only for a reader
   who has not asked for less movement. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes fl-work {
    from { opacity: 1; }
    to   { opacity: 0.55; }
  }
  .flash-console[data-phase="writing"] .flash-lamp-dot {
    animation: fl-work 1.1s ease-in-out infinite alternate;
  }
}

/* --------------------------------------------------------------------------
   The gate

   The switch itself is the site-wide one: a real checkbox, a thumb that moves
   and a tick that appears, already agreed across every form here. Only its
   housing is added, so the gate reads as part of the console rather than as a
   form field that wandered in.
   -------------------------------------------------------------------------- */
.flash-install .consent {
  padding: var(--step-4);
  border-radius: var(--radius-sm);
  background-color: var(--sk-metal-lo);
  background-image: var(--sk-knurl);
  box-shadow: var(--sk-recess);
}

.flash-console[data-phase="idle"] .flash-ack-state { color: var(--fl-lamp-wait); }
.flash-console[data-phase="ready"] .flash-ack-state { color: var(--fl-lamp-good); }

/* --------------------------------------------------------------------------
   The key

   Travel and a shadow inversion together, so the press is felt rather than
   only tinted. The base pill is the site's; only the depth is added here.
   -------------------------------------------------------------------------- */
.flash-key-install:not([disabled]):active {
  transform: translateY(2px);
  box-shadow:
    inset 0 3px 7px rgba(0, 0, 0, 0.75),
    inset 0 -1px 0 rgba(255, 255, 255, 0.05);
}

/* Folded to one column, the key takes the width it is given. It is the only
   control here and it is pressed with a thumb. */
/* The label is one sentence, not a row of parts. As a flex row the version
   span became its own item and the words dealt themselves into columns on a
   narrow screen, so the key lays its label out as text. */
.flash-key-install {
  display: block;
  text-align: center;
  text-wrap: balance;
}

@media (max-width: 40rem) {
  .flash-install esp-web-install-button,
  .flash-key-install { width: 100%; }
}

/* A locked key is a key with no power behind it, not a broken one: it keeps
   its shape and loses its backlight. */
.flash-key-install[disabled] {
  filter: saturate(0.25);
}

/* --------------------------------------------------------------------------
   The pre-flight card and the reading slabs
   -------------------------------------------------------------------------- */
.flash-preflight {
  padding: var(--step-4) var(--step-5);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(255, 255, 255, 0.06);
  background-color: var(--sk-metal-lo);
  background-image: var(--sk-plate-face);
  box-shadow: var(--sk-bevel);
}

/* The tables sit on a flat slab. No grain, no gradient: this is paper mounted
   in the instrument, and it holds nothing but reading. */
.build-slab {
  background-image: none;
  background-color: var(--surface-reading, var(--color-surface-alt));
  border: 1px solid rgba(255, 255, 255, 0.06);
  box-shadow: var(--sk-recess);
}

/* The board button names are keycaps, because that is what they are. */
.flash-key {
  background-image: var(--sk-plate-face);
  background-color: var(--sk-metal);
  border-color: rgba(0, 0, 0, 0.7);
  box-shadow:
    inset 0 1px 0 var(--sk-edge-lit-2),
    0 1px 2px rgba(0, 0, 0, 0.6);
}

/* The step numerals are stamped discs rather than flat dots. */
.flash-steps > li::before {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    inset 0 -1px 2px rgba(0, 0, 0, 0.35),
    0 1px 3px rgba(0, 0, 0, 0.6);
}

/* The three requirement boxes are labels stuck to the panel. */
.flash-need {
  background-image: var(--sk-plate-face);
  background-color: var(--sk-metal-lo);
  border-color: rgba(255, 255, 255, 0.06);
  box-shadow: var(--sk-bevel);
}

/* The outcome banners keep the flat treatment: an outcome is information, and
   information does not get texture. */
.flash-banner {
  background-image: none;
  background-color: var(--surface-reading, var(--color-surface-alt));
}

/* The manual route's terminal block. */
.flash-manual pre {
  background-color: var(--sk-glass);
  background-image: repeating-linear-gradient(180deg,
    transparent 0 3px, var(--sk-scanline) 3px 4px);
  border-color: rgba(0, 0, 0, 0.8);
  box-shadow: var(--sk-recess);
}

/* --------------------------------------------------------------------------
   Fallbacks
   -------------------------------------------------------------------------- */
@media (forced-colors: active) {
  .flash-console,
  .flash-glass,
  .flash-preflight,
  .build-slab,
  .flash-install .consent input[type="checkbox"] { border: 1px solid; }

  .flash-console * { text-shadow: none; }

  .flash-screw { display: none; }
}

/* --------------------------------------------------------------------------
   The photo rail bleeds 5rem past the row at both ends, which is the point of
   it; on a narrow screen the right-hand end of that bleed was widening the
   page itself. Clipping at the section keeps the bleed running off the edge
   of the screen instead of off the edge of the row.
   -------------------------------------------------------------------------- */
.section:has(.photos) { overflow-x: clip; }

/* --------------------------------------------------------------------------
   The narrowest screens.

   Panel padding, console padding and a two-column consent grid compounded: at
   320px the sentence beside the switch was left an 85px column and ran to
   eleven lines. The switch takes its own row there and the plates give their
   padding back to the text.
   -------------------------------------------------------------------------- */
@media (max-width: 30rem) {
  .flash-panel,
  .flash-console { padding: var(--step-2); }

  .flash-install .consent {
    grid-template-columns: 1fr;
    gap: var(--step-2);
    padding: var(--step-2);
  }

  .flash-install .consent input[type="checkbox"] { margin-top: 0; }

  .flash-install esp-web-install-button,
  .flash-key-install { width: 100%; }
}

/* --------------------------------------------------------------------------
   The command block's copy key.

   The one code block on the site. The key is the guide's micro-key: a small
   plate on the rim of the channel, with real travel and an accent-lit
   confirmation that clears itself.
   -------------------------------------------------------------------------- */
.flash-code { position: relative; }

.flash-code pre { padding-right: var(--step-8); }

.flash-copy {
  position: absolute;
  top: var(--step-3);
  right: var(--step-3);
  padding: 0.25em 0.7em;
  border: 0;
  border-radius: var(--radius-tight);
  font-family: var(--font-mono);
  font-size: var(--size-2xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  cursor: pointer;
  color: var(--color-text-muted);
  background: var(--sk-plate-face);
  box-shadow:
    inset 0 1px 0 var(--sk-edge-lit-2),
    0 2px 0 var(--sk-rubber),
    0 3px 5px rgba(0, 0, 0, 0.5);
}

.flash-copy:hover { color: var(--color-text); }

.flash-copy:active {
  transform: translateY(2px);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.7);
}

.flash-copy[data-done] {
  color: var(--color-accent);
  box-shadow:
    inset 0 1px 3px rgba(0, 0, 0, 0.7),
    0 0 0 1px color-mix(in srgb, var(--color-accent) 40%, transparent);
}

.flash-copy:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .flash-copy:active { transform: none; }
}

@media (forced-colors: active) {
  .flash-copy { border: 1px solid; }
}

/* --------------------------------------------------------------------------
   Flat again, to match the home page.

   Everything on this page that is not the console plate itself had drifted
   into moulded metal: keycaps with a gradient and an inset highlight, a
   scanlined glass window, a plated pre-flight card, a glossy install key and
   step numerals set as lit discs. The home page sets none of those, and this
   is the page a reader reaches it from.

   The console keeps its raised face: it is the device object. Its contents do
   not. The selectors are doubled because the surfaces sheet loaded after this
   one owns the same single-class rules.
   -------------------------------------------------------------------------- */

/* Keycaps: a hairline box around a mono word, nothing behind it. */
.flash-key.flash-key {
  background-image: none;
  background-color: var(--color-surface-high);
  border: var(--hairline) solid var(--color-border-strong);
  box-shadow: none;
  text-shadow: none;
}

/* The status window stays a dark well, without the coating or the recess. */
.flash-glass.flash-glass {
  background-image: none;
  background-color: var(--sk-glass);
  border: var(--hairline) solid var(--color-border-strong);
  box-shadow: none;
}

/* Pre-flight is a panel of reading, so it is hairline like every other one. */
.flash-preflight.flash-preflight {
  background-image: none;
  background-color: var(--color-surface-alt);
  border: var(--hairline) solid var(--color-border);
  box-shadow: none;
}

/* The install key is the site's primary pill, exactly as the home page draws
   it: flat accent, page-coloured label, no gloss and no glow. */
.flash-key-install.flash-key-install,
.flash-key-install.flash-key-install:not([disabled]) {
  background-image: none;
  background-color: var(--color-accent);
  color: var(--color-page);
  border-color: transparent;
  box-shadow: none;
  text-shadow: none;
}

.flash-key-install.flash-key-install::before,
.flash-key-install.flash-key-install::after { content: none; }

.flash-key-install.flash-key-install:not([disabled]):hover {
  background-color: color-mix(in srgb, var(--color-accent) 84%, white);
  color: var(--color-page);
  box-shadow: none;
  transform: none;
}

.flash-key-install.flash-key-install:not([disabled]):active {
  transform: none;
  box-shadow: none;
}

/* A locked key keeps the pill's shape and loses its power, rather than being
   re-moulded into the sunken plate the shared disabled rule draws. */
.flash-key-install.flash-key-install:disabled {
  background-image: none;
  background-color: var(--color-accent);
  color: var(--color-page);
  border: 0;
  box-shadow: none;
  text-shadow: none;
}

/* The step numerals take the home page's treatment: a faint display numeral
   in the gutter rather than a lit disc. */
.flash-steps.flash-steps > li::before {
  width: 2.75rem;
  height: auto;
  display: block;
  background: none;
  border-radius: 0;
  box-shadow: none;
  font-family: var(--font-display);
  font-size: var(--size-2xl);
  font-weight: 700;
  line-height: 1;
  color: var(--s6-num, rgba(255, 255, 255, 0.28));
  text-shadow: none;
}
