/* ===========================================================================
   MATRI — Agent T · DATA RAIN / GLITCH entry portal (p6)
   Palette: fresh cyan + lime on near-black. Technical mono. Terminal key line.
   Strict-CSP: no inline styles; JS drives dynamic values via CSSOM/classList.
   Rebuilt fully responsive: fluid terminal card, viewport-fit glyph rain,
   gate reachable at 390x844 (portrait), 844x390 (landscape), and desktop.
   =========================================================================== */

:root {
  /* near-black substrate */
  --void:   #05070a;
  --void-2: #070b0f;
  --panel:  rgba(9, 14, 19, 0.72);
  --panel-solid: #090e13;

  /* signal colors */
  --cyan:   #2de2c6;   /* primary head glyph, focus, prompt */
  --cyan-hi:#7cffe9;
  --lime:   #c6ff4a;   /* accent surge / run button */
  --lime-hi:#e7ff9c;

  /* glitch RGB-split channels */
  --glitch-a: #ff2e6e; /* magenta-red */
  --glitch-b: #21d4ee; /* cyan-blue   */

  /* ink */
  --ink:    #d7e6e6;   /* body text — ~13:1 on --void */
  --ink-dim:#8aa2a3;   /* ~6.5:1 on --void */
  --ink-fnt:#5c7375;   /* faint labels — used only at >=14px on dark */
  --hair:   rgba(45, 226, 198, 0.16);
  --hair-2: rgba(45, 226, 198, 0.08);

  --mono: ui-monospace, "Cascadia Code", "JetBrains Mono", "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --r: 12px;
  --ease: cubic-bezier(.2, .7, .2, 1);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  min-height: 100svh;
  background: var(--void);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  display: grid;
  place-items: center;
  padding: max(20px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
           max(20px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  /* Only the horizontal axis is clamped — vertical can scroll so the gate is
     always reachable when a short landscape viewport can't fit the card. */
  overflow-x: hidden;
  overflow-y: auto;
}

/* ---- skip link ---- */
.skip {
  position: fixed; left: 12px; top: -60px; z-index: 40;
  background: var(--panel-solid); color: var(--cyan);
  border: 1px solid var(--cyan); border-radius: 8px;
  padding: 10px 14px; font-size: 13px; text-decoration: none;
  transition: top .18s var(--ease);
}
.skip:focus { top: 12px; }

/* ---- backdrop layers ---- */
.rain {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; display: block;
  background: radial-gradient(120% 120% at 50% 8%, #08111a 0%, var(--void) 62%);
}

/* ---- gesture-tech showcase overlay (8 demos render here, behind the card) ---- */
.fx {
  position: fixed; inset: 0; z-index: 2;
  pointer-events: none; overflow: hidden;
}
.fx__canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%; display: block;
}
.fx-label {
  position: fixed; z-index: 5;
  left: 50%; top: max(12px, env(safe-area-inset-top));
  transform: translateX(-50%);
  margin: 0; pointer-events: none;
  max-width: calc(100vw - 24px);
  padding: 6px 14px;
  font-size: 10.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--cyan);
  background: rgba(5, 7, 10, .74);
  border: 1px solid var(--hair);
  border-radius: 999px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; transition: opacity .3s var(--ease);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.fx-label.show { opacity: 1; }

/* click-and-hold demo: stacked translucent columns, additively phosphor-glowing */
.layerfx { position: absolute; inset: 0; }
.layerfx__col {
  position: absolute; top: -20%; height: 140%;
  mix-blend-mode: screen;
  background: linear-gradient(180deg,
    transparent 0%,
    rgba(45, 226, 198, .42) 38%,
    rgba(198, 255, 74, .40) 60%,
    transparent 100%);
  filter: blur(1px);
  opacity: .85;
  animation: layerdrift 2.6s var(--ease) infinite alternate;
  animation-delay: calc(var(--i, 0) * -0.34s);
}
@keyframes layerdrift {
  from { transform: translateY(-14%) scaleY(.82); }
  to   { transform: translateY(14%)  scaleY(1.16); }
}

.grain {
  position: fixed; inset: 0; z-index: 3; pointer-events: none;
  opacity: .05; mix-blend-mode: screen;
  background-image:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(45,226,198,.5) 2px 3px);
  background-size: 100% 3px;
}
.vignette {
  position: fixed; inset: 0; z-index: 4; pointer-events: none;
  background:
    radial-gradient(130% 100% at 50% 46%, transparent 40%, rgba(3,5,7,.62) 78%, rgba(3,5,7,.92) 100%);
}

/* ---- shell / centered terminal ---- */
.stage {
  position: relative; z-index: 6;
  width: min(560px, 100%);
  min-width: 0;            /* grid item: allow shrink to area, no min-content overflow */
  max-width: 100%;
  display: flex; justify-content: center;
}

.term {
  position: relative;
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--hair);
  border-radius: var(--r);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.4),
    0 30px 80px -30px rgba(0,0,0,.9),
    0 0 60px -20px rgba(45,226,198,.22);
  overflow: hidden;
  opacity: 0;
  transform: translateY(10px) scale(.99);
  animation: term-in .7s var(--ease) .05s forwards;
}
@keyframes term-in { to { opacity: 1; transform: none; } }

/* denied: chromatic-aberration shake (bounded, no >3/s strobe) */
.term.is-deny { animation: deny-shake .5s var(--ease) both; }
@keyframes deny-shake {
  0%, 100% { transform: translateX(0); box-shadow: 0 0 0 1px rgba(0,0,0,.4), 0 30px 80px -30px rgba(0,0,0,.9), 0 0 60px -20px rgba(45,226,198,.22); }
  10% { transform: translateX(-7px); box-shadow: 6px 0 0 -2px var(--glitch-a), -6px 0 0 -2px var(--glitch-b), 0 30px 80px -30px rgba(0,0,0,.9); }
  30% { transform: translateX(6px); }
  50% { transform: translateX(-4px); box-shadow: 4px 0 0 -2px var(--glitch-a), -4px 0 0 -2px var(--glitch-b), 0 30px 80px -30px rgba(0,0,0,.9); }
  70% { transform: translateX(3px); }
  85% { transform: translateX(-1px); }
}

/* ---- title bar ---- */
.term__bar {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hair-2);
  background: linear-gradient(180deg, rgba(45,226,198,.05), transparent);
}
.term__dots { display: inline-flex; gap: 7px; flex: none; }
.term__dots .dot { width: 11px; height: 11px; }
.term__dots .dot:nth-child(1) { color: #ff5f57; }
.term__dots .dot:nth-child(2) { color: #f7c94b; }
.term__dots .dot:nth-child(3) { color: var(--cyan); }
.term__dots .dot circle { fill: currentColor; opacity: .9; }
.term__title {
  font-size: 12.5px; letter-spacing: .04em; color: var(--ink-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
/* .term__link and .term__link .lock went with the TLS badge they styled - see wall/p6/index.html
   at the title bar for why. Nothing else referenced either rule. */


/* ---- body ---- */
.term__body { padding: 30px clamp(20px, 5vw, 34px) 26px; }

.brand {
  position: relative;
  margin: 0 0 20px;
  font-size: 13px; font-weight: 700; letter-spacing: .42em;
  color: var(--cyan);
  text-indent: .42em;
}
.brand::before {
  content: "// ";
  color: var(--ink-fnt); letter-spacing: normal; text-indent: 0; font-weight: 400;
}

.head {
  position: relative;
  margin: 0 0 14px;
  font-size: clamp(23px, 6vw, 33px);
  font-weight: 650;
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ink);
}
/* RGB-split glitch layers on the headline (data-text mirror) */
.head::before, .head::after {
  content: attr(data-text);
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: 0;
  clip-path: inset(0 0 0 0);
}
.head::before { color: var(--glitch-a); }
.head::after  { color: var(--glitch-b); }
.term.is-glitch .head::before { animation: split-a .42s steps(2) both; }
.term.is-glitch .head::after  { animation: split-b .42s steps(2) both; }
@keyframes split-a {
  0% { opacity: 0; transform: translate(0,0); }
  20% { opacity: .9; transform: translate(-3px,-1px); clip-path: inset(0 0 62% 0); }
  45% { transform: translate(2px,1px); clip-path: inset(58% 0 8% 0); }
  70% { transform: translate(-2px,0); clip-path: inset(20% 0 46% 0); }
  100% { opacity: 0; transform: translate(0,0); }
}
@keyframes split-b {
  0% { opacity: 0; transform: translate(0,0); }
  25% { opacity: .9; transform: translate(3px,1px); clip-path: inset(72% 0 0 0); }
  50% { transform: translate(-2px,-1px); clip-path: inset(10% 0 70% 0); }
  75% { transform: translate(2px,0); clip-path: inset(40% 0 30% 0); }
  100% { opacity: 0; transform: translate(0,0); }
}

.sub {
  margin: 0 0 26px;
  max-width: 46ch;
  font-size: 13.5px; line-height: 1.6;
  color: var(--ink-dim);
}

/* ---- the terminal key line ---- */
.key { margin: 0; }
.key__label {
  display: block;
  font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-fnt);
  margin-bottom: 9px;
}

.prompt {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding: 12px 12px 12px 14px;
  background: rgba(3, 6, 9, .66);
  border: 1px solid var(--hair);
  border-radius: 10px;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.prompt:focus-within {
  border-color: var(--cyan);
  background: rgba(3, 6, 9, .82);
  box-shadow: 0 0 0 3px rgba(45,226,198,.22), 0 0 26px -8px rgba(45,226,198,.5);
}
.prompt__ps1 {
  flex: none;
  color: var(--cyan); font-size: 13.5px; letter-spacing: .01em;
  opacity: .92; user-select: none;
}
/* field flexes to fill and can shrink below content — the key overflow fix:
   the input width is now bounded by the container, never grown past it. */
.prompt__field { position: relative; flex: 1 1 120px; display: flex; align-items: center; min-width: 0; }
.prompt__input {
  flex: 1 1 auto; width: 100%; min-width: 0;
  appearance: none; background: transparent; border: 0; outline: none;
  color: var(--ink); font: inherit; font-size: 15px;
  letter-spacing: .12em;
  caret-color: var(--cyan);
  padding: 2px 0;
}
.prompt__input::placeholder { color: var(--ink-fnt); letter-spacing: normal; }
.prompt__input:-webkit-autofill { -webkit-text-fill-color: var(--ink); transition: background-color 9999s; }

/* run button */
.run {
  flex: none; margin-left: auto;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px;
  font: inherit; font-size: 13px; font-weight: 700; letter-spacing: .06em;
  color: var(--void);
  background: var(--lime);
  border: 0; border-radius: 8px;
  cursor: pointer;
  transition: transform .15s var(--ease), filter .15s var(--ease), opacity .2s, background .2s;
}
.run__ico { width: 17px; height: 17px; }
.run:hover:not(:disabled) { filter: brightness(1.08); transform: translateY(-1px); }
.run:active:not(:disabled) { transform: translateY(0) scale(.98); }
.run:disabled { background: #1b2a2a; color: var(--ink-fnt); cursor: progress; }

/* ---- verdict (aria-live) ---- */
.verdict {
  min-height: 1.3em; margin: 14px 2px 0;
  font-size: 13px; letter-spacing: .01em; color: var(--ink-dim);
  transition: color .2s;
}
.verdict:not(:empty)::before { content: "> "; color: var(--ink-fnt); }
.verdict.is-work { color: var(--cyan); }
.verdict.is-deny { color: var(--glitch-a); }
.verdict.is-wait { color: var(--lime); }

/* ---- meta / footer key line ---- */
.meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 24px; padding-top: 16px;
  border-top: 1px solid var(--hair-2);
  font-size: 11.5px; letter-spacing: .04em; color: var(--ink-fnt);
}
.meta__cell { white-space: nowrap; }
/* .meta__sep went with the two separators it styled - see the meta row in wall/p6/index.html. */
.meta__ver { margin-left: auto; color: var(--ink-dim); }
#status.is-live { color: var(--cyan); }

/* ---- gesture signal caption ---- */
.gestures {
  display: flex; flex-wrap: wrap; align-items: center; gap: 7px 10px;
  margin: 14px 2px 0;
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-fnt);
}
.gestures__k {
  padding: 3px 8px;
  border: 1px solid var(--hair);
  border-radius: 999px;
  color: var(--ink-dim);
}
.gestures__t { color: var(--ink-fnt); letter-spacing: .08em; }

/* ---- focus-visible ring everywhere ---- */
:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 4px; }
.run:focus-visible { outline-offset: 3px; }
.prompt__input:focus-visible { outline: none; }

/* ===========================================================================
   THE CROSSING — channel opens: scene warps, panel dissolves into the stream
   =========================================================================== */
html.crossing .term {
  animation: cross-out 1.4s var(--ease) forwards;
}
@keyframes cross-out {
  0%   { opacity: 1; transform: none; filter: none; }
  14%  { transform: translateX(-4px); box-shadow: 8px 0 0 -3px var(--glitch-a), -8px 0 0 -3px var(--glitch-b); }
  28%  { transform: translateX(5px); }
  44%  { transform: translateX(-2px) scale(1.004); }
  60%  { opacity: 1; transform: scale(1.02); filter: brightness(1.25) blur(.4px); }
  100% { opacity: 0; transform: scale(1.12); filter: brightness(2) blur(6px); }
}
html.crossing .vignette { animation: cross-fade 1.4s var(--ease) forwards; }
@keyframes cross-fade { to { background: radial-gradient(130% 100% at 50% 46%, rgba(45,226,198,.14) 0%, transparent 55%, rgba(3,5,7,.6) 100%); } }

/* ===========================================================================
   RESPONSIVE — portrait phones
   =========================================================================== */
@media (max-width: 480px) {
  body { padding: 16px 14px max(16px, env(safe-area-inset-bottom)); }
  .term__body { padding: 24px 18px 20px; }
  .term__title { font-size: 11.5px; }
  .brand { letter-spacing: .34em; }
  .run { padding: 9px 12px; }
}
@media (max-width: 360px) {
  .prompt__ps1 { font-size: 12px; }
  .brand { letter-spacing: .28em; }
}

/* ===========================================================================
   RESPONSIVE — short / landscape viewports (e.g. 844x390)
   Compact the card so the gate stays fully on-screen; body still scrolls
   as a last resort so the run button is never unreachable.
   =========================================================================== */
@media (max-height: 560px) {
  body { padding: 12px 16px; place-items: center; }
  .term__bar { padding: 8px 14px; }
  .term__body { padding: 16px clamp(16px, 4vw, 28px) 14px; }
  .brand { margin-bottom: 10px; }
  .head { font-size: clamp(19px, 4.4vh, 25px); margin-bottom: 8px; }
  .sub { margin-bottom: 14px; font-size: 12.5px; line-height: 1.5; }
  .key__label { margin-bottom: 6px; }
  .verdict { margin-top: 10px; min-height: 1.1em; }
  .meta { margin-top: 12px; padding-top: 10px; }
  .gestures { margin-top: 10px; }
}
/* very short landscape: hide the descriptive paragraph to guarantee fit */
@media (max-height: 430px) and (orientation: landscape) {
  .sub { display: none; }
  .gestures { display: none; }
  .term__body { padding: 14px 20px 12px; }
  .head { font-size: clamp(18px, 5.6vw, 23px); }
}

/* ===========================================================================
   REDUCED MOTION — pause every heavy animation to a still, quiet frame
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .term { opacity: 1; transform: none; animation: none; }
  .term.is-deny { animation: none; }
  .term.is-glitch .head::before, .term.is-glitch .head::after { animation: none; opacity: 0; }
  html.crossing .term { animation: none; opacity: .25; transition: opacity .3s; }
  html.crossing .vignette { animation: none; }
  .layerfx__col { animation: none; }
  .skip { transition: none; }
  .grain { display: none; }
}

/* exit veil: the LAST painted frame before leaving must match the app's dark canvas (#0b0d12) so the
   browser never shows a bright frame between documents — photosensitivity mandate, applies to every exit */
.exit-veil{ position:fixed; inset:0; z-index:2147483000; background:#0b0d12; opacity:0; pointer-events:none; transition:opacity .3s ease; }
.exit-veil.is-on{ opacity:1; }
@media (prefers-reduced-motion: reduce){ .exit-veil{ transition:none; } }


/* =========================================================================================================
   BIND PORT - THE CHIP'S LANE, AND THE KEYBOARD'S OWN VIEWPORT STATE
   PORT-NOTES STEP 7 - R319/§312 SESSION-BIND, piece portals-p4p5p6p7. ASL v2 Laws 1, 3, 4, 5 and 11;
   brief items 6, 26, 27, 28 and 33.

   Everything above this line is the host's: the scene, the type, the copy, the colours, the key form's
   markup. This block is the one thing bind.com puts on the door that the host never had -
   wall/shared/motion.css, which fixes the shared sensor chip to the block-end corner of the VIEWPORT at
   calc(14px + env(safe-area-inset-bottom)). A fixed element does not scroll, so a document that scrolls
   underneath it can never end above it, and the profile ASL Law 11 names - Keyboard-open, 390 x 430 - is
   exactly where a door's key row lands in the corner the chip is fixed in.

   THE LANE is PORT-NOTES STEP 7's own string, and it is a reservation, not a restyle: the chip is never
   moved, shrunk, hidden or dropped to make the room. 52px is the chip's tallest measured box (44px at 390
   and above, 52px at 320 and 344 where its armed line wraps to two); 14px is the inset the chip already
   sits at, and 14px more is the gutter between the two; the safe-area inset is added again because the
   chip's own position carries it. tests/portal-gate.mjs re-measures the real chip at both widths on every
   run, so a chip that ever grows reddens the arm instead of quietly eating a row.

   THE SHELL IS THE SCROLL REGION (ASL Law 4). The document is clipped and <body> scrolls, so the scrolling
   box's block-end edge IS the lane's block-start edge by construction - no scroll offset exists that can
   park the key row under the chip. The scene layers stay fixed to the whole viewport and are unchanged:
   only the door's own content column ends higher.
   ========================================================================================================= */
:root { --b-lane: calc(52px + 28px + env(safe-area-inset-bottom, 0px)); }

html { overflow: hidden; }
body {
  /* the host's own `min-height: 100dvh` is the viewport, and a min-height outranks a height: it has to be
     released here or the shell keeps the whole screen and the lane is a promise the layout never keeps. */
  min-block-size: 0;
  block-size: calc(100dvh - var(--b-lane));
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}

/* SAFE CENTRING (ASL Law 8: reading order survives reflow). The shell can scroll now, and a centred column
   that outgrows its scrollport puts its own START out of reach - no scroll offset can go above zero.
   MEASURED on p4, the widest-typed of the four, before this rule went in: at 1440x900 the shell is 820 px,
   the content 1069, and the brand row sat at y -80. Every door whose content can outgrow its shell has the
   same shape available to it, so all four carry the keyword; it changes nothing at any size where the door
   fits.
   Here body is BOTH the grid that centres the terminal and the scroll region, so the keyword goes on it. */
body { align-content: safe center; }


/* ASL Law 5 and estate L6. MEASURED on the host at 390 x 844, pointer:coarse: the prompt input is 24 CSS
   px tall (padding 2px on a 15px line) and the run button is 35 - the terminal's whole idiom is a thin
   command line, so the floor is met with min-block-size and nothing else changes. */
@media (pointer: coarse) {
  .prompt__input { min-block-size: 44px; }
  .run { min-block-size: 44px; }
}

/* The scroll-margin box is what "scroll an element into view" uses, so it is how a focused field brings
   the rest of its row with it. It is only needed where the row WRAPS and the primary action sits below
   the field - below 560px on the prompt, which is exactly where the host makes the action full-width.
   RE-MEASURED ON THIS DOOR 2026-08-31, AFTER THE LOAD-TIME FOCUS WENT (wall/p6/index.html carries the
   reason, and this rule is half of why it had to go). Round 1 wrote three figures here that were taken
   on p4 and never re-taken on p6, and round 2 had already refuted them even on p4; they are corrected
   rather than repeated. The honest numbers, taken by giving the field the visitor's OWN keyboard focus
   on the shipped door (probe/_diag11.mjs, both arms, six profiles):
     390x430   without the rule the focus scrolls 0 px and the `run` button is BELOW the shell; with it,
               96 px and the field and the button are both wholly on. THE RULE EARNS ITS PLACE HERE, and
               this is the only profile at which it does.
     320x568   103 px with the rule, 0 px without; the button is wholly on either way, so here the rule
               buys headroom rather than reach.
     1440x900, 1194x834, 844x390, 390x844   0 px either way - above 560px the action is beside the field
               and the door fits its shell, which is the whole reason the large value is scoped below it.
   AND THE COST, which is why index.html changed in the same commit: while the host's `autofocus` was
   still on the field, this 132 px was spent on a focus nobody asked for, and it landed the door 106 px
   into its own scene at 390x430 and 112 px at 320x568 - past the MATRI brand row, by 93 and 95 px. The
   margin is right; being spent on load was not. There is no load scroll of any size now. */
.prompt__input { scroll-margin-block: 16px 28px; }
@media (max-width: 560px) { .prompt__input { scroll-margin-block-end: 132px; } }


/* =========================================================================================================
   BIND PORT - THE ASL v2 SECTION 5 MATRIX, ROW BY ROW   (R319/S312 SESSION-BIND, piece portals-p4p5p6p7)
   Brief items 26, 27, 28, 34, 35, 36. Nothing here is taste: every rule below was written against a named
   offender that tests/matrix.mjs printed on a real render of THIS door, and the run that named it is in
   evidence/portals-p4p5p6p7-r1/. The host never ran the matrix on these seven pages; bind.com does.
   ========================================================================================================= */

/* SAFE AREA (section 5 assertion 6). The harness's rule is geometric: no fixed element's CONTENT box may
   lie inside an inset band, and its own selection record names the escape - an element that pads with
   env(safe-area-inset-*) declares that its content clears the band. These layers are the scene: aria-hidden,
   pointer-events:none, painted, never read and never tapped. Padding is free for a box whose paint is a
   background or whose children are positioned against its padding box (that box does not move). It is NOT
   free for a <canvas>: the bitmap is scaled into the content box, so on a device that reports a notch the
   decorative field is rescaled by up to (47+34)/844 = 9.6 per cent in the block axis and by nothing at all
   on every device that reports no inset. That rescale was measured and accepted; the alternative was to
   leave the layers full-bleed and hand back thirty-five red rows on a rule the estate treats as a build
   failure. Nothing readable and nothing tappable is inside either band - the first flow text and every
   control are recorded per row in matrix-results.json. */
.rain, .fx, .grain, .vignette {
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
           env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

/* THE SKIP LINK, AND THE KEYBOARD-OPEN PROFILE. The harness refuses a FIXED element parked entirely outside
   the viewport, because at 390x430 a fixed element the layout has forgotten is exactly what strands a
   control. A skip link parked off-screen until focus is the standard pattern and it is kept - as an
   ABSOLUTE element, which is what p5's own host already does, so it belongs to the document that scrolls
   rather than to the viewport the chip is fixed to. Its offsets, its colours and its copy do not change. */
.skip { position: absolute; }

@media (pointer: coarse) {
  .skip { display: inline-flex; align-items: center; min-block-size: 44px; }
}

@media (forced-colors: active) {
  .skip, .prompt__input, .run { border: 1px solid ButtonBorder; }
  .skip { text-decoration: underline; }
}

@media (horizontal-viewport-segments: 2) {
  .stage { max-inline-size: 44%; margin-inline: 4% auto; }
}

/* ZOOM 200% (section 5 cross-cut). Two offenders were measured at mobileS and folded, where the layout
   viewport is 160 and 172 CSS px: the TLS badge, which is gone (see the title bar in wall/p6/index.html),
   and the stdin counter, which ran from 33 to 184 in a 160 px viewport. The status line's cells may break
   inside a word now rather than push the row wider, and the title bar is allowed to wrap for the same
   reason the status row already was. .term__title needs nothing: it is white-space: nowrap with an
   ellipsis and a min-width of 0 already, so it shrinks instead of pushing. */
.term__bar { flex-wrap: wrap; }
.meta__cell { min-inline-size: 0; overflow-wrap: anywhere; }

/* VISIBLE FOCUS ON THE KEY FIELD (section 5 assertion 4, estate L6, brief item 21 - the floor that
   outranks spectacle, always). THIS IS THE OTHER HALF OF THE ROUND'S ONE GAP, not a second gap: taking
   the load-time focus off the field is what lets a Tab traversal ARRIVE at it for the first time, and
   what it arrives at is nothing. MEASURED on a real keyboard traversal of the shipped door
   (probe/_diag11.mjs, two Tab presses from the top of the document, all six profiles):
     input#key   outline-style NONE. Not a thin ring, not a low-contrast one - none.
   The cause is a specificity accident in the host's own stylesheet, twenty-six lines apart:
     line 357  `:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 4px }`
               scores (0,1,0) and is the ring every control on this door wears;
     line 359  `.prompt__input:focus-visible { outline: none }` scores (0,2,0) and takes it back from the
               one field the door exists for.
   So nothing here is invented and nothing of the host's is deleted: the door's own three declarations,
   copied from its own line 357, re-stated at a weight that lands (same (0,2,0), later in source order).
   The `.prompt` box's :focus-within treatment stays exactly as it is - it is a border-colour change plus
   a 3 px glow at 22 per cent alpha on the PARENT, which is a good terminal-idiom touch and is not a focus
   indicator on the focused element. p4's line for this, added in round 2, is the same line. */
.prompt__input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 4px; }
