/* THE TERMINAL — a console still running in a building nobody maintains.
 *
 * "The system is still running. Nobody is maintaining it."
 *
 * Ported from Brennan's dystopian theme, which is where this contract came
 * from. Two things came across whole and are the reason it reads as a place
 * rather than a palette: MATERIALS declared once and reused everywhere
 * (concrete, board-form, aggregate, steel, hazard tape, phosphor), and the
 * fact that the room owns its own frame — see templates/rooms/dystopian/.
 *
 * Everything runs off --dystopian-spd, written by room-weather.js from the
 * reader's dial. At Clean Signal the tear is a rumour; at The Oracle Answers
 * Anyway it will not hold still.
 */

[data-room="dystopian"] {
  --dystopian-spd: 6s;          /* room-weather.js overwrites from the dial */
  --dystopian-bar-spd: 3s;

  /* --- materials, not colours. Declared once, reused in every slot. ------ */
  --dy-concrete: linear-gradient(180deg, #141618 0%, #0e1011 58%, #090a0b 100%);
  /* Board-formed: the shutter lines are still in it. */
  --dy-form: repeating-linear-gradient(180deg,
              transparent 0 33px,
              rgba(0, 0, 0, .55) 33px 35px,
              rgba(255, 255, 255, .025) 35px 36px);
  /* Aggregate — the stones in the pour, catching light at four fixed points. */
  --dy-aggregate:
    radial-gradient(circle at 21% 37%, rgba(255,255,255,.035) 0 1.1px, transparent 2px),
    radial-gradient(circle at 67% 19%, rgba(255,255,255,.028) 0 .9px, transparent 1.8px),
    radial-gradient(circle at 44% 78%, rgba(0,0,0,.40)     0 1.3px, transparent 2.2px),
    radial-gradient(circle at 88% 63%, rgba(255,255,255,.022) 0 .8px, transparent 1.6px);
  /* The steel's lit edge was #26292c, which is LIGHTER than any ground the
     house declares — so the house's own inks were never measured against it.
     The header, the rack and every button are drawn in this metal, and the
     nav labels on it came out 4.24:1. Taken down by scaling the linear
     channels, which keeps the hue: the same metal in less light, not a
     different metal. At #1c1e21 the house's dim ink reads 5.51:1 on it and
     the faintest 4.53:1, so nothing the site sets on this room's steel is
     below the floor the room's own tokens promise. */
  --dy-steel: linear-gradient(180deg, #1c1e21 0%, #181b1d 55%, #101213 100%);
  --dy-hazard: repeating-linear-gradient(45deg, #c8a000 0 7px, #151515 7px 14px);
  --dy-bolt: #43484c;
  --dy-phos: #00c437;
  /* The one thing on this machine that means STOP. */
  --dy-alarm: #8b0000;
}

/* Slot 2 — ground. Concrete, board-formed, with the aggregate showing. */
[data-room="dystopian"] body {
  background-color: var(--syn-void);
  background-image: var(--dy-form), var(--dy-aggregate), var(--dy-concrete);
  background-attachment: fixed;
}

/* Burned into the phosphor. Fixed, behind the reading, never interactive —
   the frame template mounts both; neither takes a pointer event. */
[data-room="dystopian"] .dy-crt,
[data-room="dystopian"] .dy-burn {
  pointer-events: none;
  z-index: -1;
}
[data-room="dystopian"] .dy-crt {
  background-image: repeating-linear-gradient(180deg,
    rgba(0, 0, 0, .28) 0 1px, transparent 1px 3px);
}
/* An interface left on for years leaves its own ghost. Static, not animated:
   burn-in does not move, that is what makes it burn-in. */
[data-room="dystopian"] .dy-burn {
  background-image: radial-gradient(ellipse at 50% 12%, rgba(0, 196, 55, .045), transparent 58%);
}

/* Slot 3 — the rule. A rack rail, bolted through. */
[data-room="dystopian"] hr,
[data-room="dystopian"] .syn-rule {
  border-color: transparent;
  background-image: var(--dy-steel),
    radial-gradient(circle at 6px 50%, var(--dy-bolt) 0 1.6px, transparent 2.4px),
    radial-gradient(circle at calc(100% - 6px) 50%, var(--dy-bolt) 0 1.6px, transparent 2.4px);
}

/* Slot 4 — the masthead is rack steel screwed to the wall. */
[data-room="dystopian"] .syn-header {
  background-color: #0c0d0f;
  background-image: var(--dy-steel);
  box-shadow: inset 0 -1px 0 rgba(0, 196, 55, .22), 0 2px 18px rgba(0, 0, 0, .65);
}
[data-room="dystopian"] .syn-mark,
[data-room="dystopian"] .syn-nav-link {
  font-family: var(--syn-mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}
[data-room="dystopian"] .syn-sigil {
  color: var(--dy-phos);
  text-shadow: 0 0 6px rgba(0, 196, 55, .55);
}

/* The room's own frame furniture (templates/rooms/dystopian/base.html). */
[data-room="dystopian"] .dy-status {
  font-family: var(--syn-mono);
  font-size: var(--t-2xs);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--dy-phos);
  background: #070809;
  border-bottom: 1px solid var(--syn-border);
}
/* Dimmer than the lit words, still a word. --syn-text-mute put UNATTENDED
   at 3.09:1 on the rack — inside the token's own declared floor, and still
   the faintest thing on a page every reader now lands on. The contrast
   between this and the phosphor beside it is what says "not lit"; it does
   not need to be at the edge of legible to say it. */
[data-room="dystopian"] .dy-status-sep,
[data-room="dystopian"] .dy-status-note { color: var(--syn-text-dim); }
[data-room="dystopian"] .dy-status-lamp {
  background: var(--dy-phos);
  box-shadow: 0 0 7px var(--dy-phos);
  border-radius: 50%;
  animation: dy-lamp calc(var(--dystopian-spd) * 0.7) steps(1, end) infinite;
}
[data-room="dystopian"] .dy-status-caret {
  background: var(--dy-phos);
  animation: dy-caret calc(var(--dystopian-spd) * 0.18) steps(1, end) infinite;
}
[data-room="dystopian"] .dy-hazard { background-image: var(--dy-hazard); }
/* The plant line — the machine's own report on itself, at the foot of the
   screen, and the mirror of .dy-status at the head of it. It was set in the
   mono face at --t-2xs in --syn-text-mute and left flush against the viewport
   edge, which read as a caption somebody forgot to style.
   A Hercules card drove one colour at 720x348 through a 9x14 character cell
   and was famous for how SHARP it was: bright phosphor on black, no colour,
   every glyph on the grid. So: the room's own display face (VT323) at a size
   where a bitmap face can show its cell, phosphor rather than grey — this is
   the machine talking, it should not be the faintest thing on the page — and
   the dot bloom a phosphor dot actually has. Centred, on a band with a rule
   top and bottom, in the idiom .dy-readout already uses.
   It stays aria-hidden in the template: set dressing, not information. */
[data-room="dystopian"] .dy-plant-line {
  font-family: var(--syn-display);
  font-size: var(--t-lg);
  line-height: 1.15;
  letter-spacing: .14em;
  word-spacing: .22em;
  text-transform: uppercase;
  text-align: center;
  color: var(--dy-phos);
  /* The bloom: a tight core and a wide halo, the way a phosphor dot spreads
     into the glass rather than the even blur of a drop shadow. */
  text-shadow: 0 0 5px rgba(0, 196, 55, .55), 0 0 18px rgba(0, 196, 55, .22);
  background-color: #060708;
  /* The character cell's own scan, one line on two off, as .dy-readout has. */
  background-image: repeating-linear-gradient(180deg,
    transparent 0 2px, rgba(0, 0, 0, .40) 2px 3px);
  border-top: 1px solid rgba(0, 196, 55, .30);
  border-bottom: 1px solid rgba(0, 196, 55, .30);
  box-shadow: inset 0 0 30px rgba(0, 196, 55, .07);
}

/* Slot 5 — a card is a panel bolted through at the corners. Three sides only:
   the fourth is `border-left: 3px solid var(--p-accent)`, the planet's own
   colour, and `border-color` is a shorthand that would grey it out. */
[data-room="dystopian"] .syn-23-section,
[data-room="dystopian"] .syn-reading,
[data-room="dystopian"] details {
  background-color: #0c0d0f;
  background-image:
    radial-gradient(circle at 11px 11px, var(--dy-bolt) 0 2.2px, #0d0f10 3.2px, transparent 4.4px),
    radial-gradient(circle at calc(100% - 11px) 11px, var(--dy-bolt) 0 2.2px, #0d0f10 3.2px, transparent 4.4px),
    var(--dy-form);
  border-top-color: var(--syn-border);
  border-right-color: var(--syn-border);
  border-bottom-color: var(--syn-border);
}

/* Slot 6 — prose. A terminal renders text; it does not set it. */
[data-room="dystopian"] .syn-passage,
[data-room="dystopian"] .syn-book-reader-body { color: var(--syn-text); }

/* Slot 8 — marks. Phosphor, with the red-green fringe of a misconverged tube. */
[data-room="dystopian"] .syn-sig,
[data-room="dystopian"] .syn-icon {
  color: var(--dy-phos);
  text-shadow: -1px 0 rgba(139, 0, 0, .55), 1px 0 rgba(0, 196, 55, .45);
}

/* Slot 9 — controls. Panel-mounted, and they light when live. */
[data-room="dystopian"] .syn-btn {
  font-family: var(--syn-mono);
  text-transform: uppercase;
  letter-spacing: .08em;
  border-color: var(--syn-border-hi);
  background-image: var(--dy-steel);
}
[data-room="dystopian"] .syn-btn:hover {
  border-color: var(--dy-phos);
  box-shadow: inset 0 0 14px rgba(0, 196, 55, .16), 0 0 10px rgba(0, 196, 55, .2);
}

/* Slot 10 — chips. Hazard tape on anything that was ever dangerous. */
[data-room="dystopian"] .syn-thread-pill:not([class*="--"]),
[data-room="dystopian"] .syn-ref {
  font-family: var(--syn-mono);
  border-color: rgba(200, 160, 0, .45);
  background-color: rgba(200, 160, 0, .07);
}

/* Slot 12 — the loading mark is a scan bar, not a wheel. */
[data-room="dystopian"] .syn-drawing {
  background-image: radial-gradient(ellipse at center, rgba(0, 196, 55, .08), transparent 62%);
}
[data-room="dystopian"] .syn-drawing-arc {
  stroke: var(--dy-phos);
  animation-duration: var(--dystopian-bar-spd);
}

/* Slot 13 — ambient. A tear, and a lamp that is not quite steady.
   Both are mostly OFF: the frame is intact for 96% of the cycle and torn for
   the rest, which is what makes it read as a fault rather than a texture. A
   glitch that is always happening is just a pattern. */
@keyframes dy-tear {
  0%, 96%  { opacity: 0; transform: translate3d(0, 0, 0); }
  97%      { opacity: .5; transform: translate3d(-2px, 1px, 0); }
  98%      { opacity: .4; transform: translate3d(2px, -1px, 0); }
  99%      { opacity: 0;  transform: translate3d(0, 0, 0); }
}
@keyframes dy-lamp  { 0%, 88% { opacity: 1; } 89%, 94% { opacity: .25; } 95% { opacity: 1; } }
@keyframes dy-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

[data-room="dystopian"] .dy-crt::after {
  content: "";
  background-image: linear-gradient(180deg,
    transparent, rgba(0, 196, 55, .10) 45%, rgba(139, 0, 0, .08) 55%, transparent);
  animation: dy-tear var(--dystopian-spd) steps(100, end) infinite;
}

/* Rule I as it now stands: a room may set geometry for ITS OWN furniture, and
   must not break the phone. These elements belong to this room and exist
   nowhere else, so nothing else can be moved by them. */
[data-room="dystopian"] .dy-crt,
[data-room="dystopian"] .dy-burn {
  position: fixed;
  inset: 0;
}
[data-room="dystopian"] .dy-crt::after {
  position: absolute;
  inset: 0;
}
[data-room="dystopian"] .dy-status {
  display: flex;
  align-items: center;
  gap: .5em;
  padding: .3rem .9rem;
}
[data-room="dystopian"] .dy-status-lamp { width: .45em; height: .45em; }
[data-room="dystopian"] .dy-status-caret { width: .5em; height: 1em; margin-left: auto; }
[data-room="dystopian"] .dy-hazard { height: 3px; }
/* Full-bleed like the status bar it mirrors, so the page is bracketed by two
   bands of machine output; the padding is what keeps the text off the glass
   edge rather than a max-width, which is how a real status line is drawn. */
[data-room="dystopian"] .dy-plant-line {
  margin: 0;
  padding: .5rem 1.1rem .42rem;
}

/* Slot 14 — reduced motion. The terminal stays ON; it stops failing.
   !important because the state variants above out-specify a bare rule. */
@media (prefers-reduced-motion: reduce) {
  [data-room="dystopian"] .dy-crt::after { animation: none !important; opacity: 0 !important; }
  [data-room="dystopian"] .dy-status-lamp { animation: none !important; opacity: 1 !important; }
  [data-room="dystopian"] .dy-status-caret { animation: none !important; opacity: 1 !important; }
  [data-room="dystopian"] .syn-drawing-arc { animation: none !important; }
}

/* Tear bars, injected and removed by js/room-glitch.js. `screen` so they add
   light across the reading rather than painting over it, and above the weather
   but below nothing else — a tear is on the glass, not in the room. */
.syn-glitch-bar {
  position: fixed;
  left: 0;
  right: 0;
  pointer-events: none;
  z-index: 200;
  mix-blend-mode: screen;
}

/* The rest of what js/room-glitch.js injects: a hazard ring round a control,
   a phosphor bloom, a block cursor, a copy of a label for the sync roll and
   the ghost, corner marks for the radius collapse, and dead pixels.
   Unscoped for the same reason as the tear bar above — the engine belongs to
   any room that declares `glitch: true`, and this is the only sheet that
   does. Every one is FIXED: damage to a tube is on the glass, not in the
   document, so none of it can reflow the page or take a pointer. The rest of
   each node — where it is, how big, what colour — is written inline by the
   engine from the target's own rect and the room's own inks. */
.dy-fx {
  position: fixed;
  pointer-events: none;
  z-index: 200;
}
/* The room's real hazard tape, cut to a ring by a clip-path the engine
   computes: a border on the control itself would be a reflow. */
.dy-fx-tape {
  background-image: var(--dy-hazard);
  opacity: .2;
}
/* These two swell and die rather than snapping, which is what makes them read
   as phosphor and not as a border being toggled. */
.dy-fx-glow,
.dy-fx-copy { transition: opacity .18s linear; }
.dy-fx-copy {
  white-space: nowrap;
  overflow: hidden;
}
.dy-fx-caret { animation: dy-caret .5s steps(1, end) infinite; }
.dy-fx-dot { border-radius: 50%; }

@media (prefers-reduced-motion: reduce) {
  /* Belt and braces: the engine returns early under reduced motion and never
     injects any of this, so this rule should be unreachable. Rule VI does not
     take "unreachable" for an answer, and neither should anyone reading it. */
  .dy-fx-caret { animation: none !important; opacity: 1 !important; }
}

/* THE OWNED PAGE — templates/rooms/dystopian/oracle/horoscope.html.
   The horoscope as a system readout. These classes exist in no other theme
   and nowhere in the site sheet, so they are the Terminal's own furniture and
   may be laid out freely (Rule I is ownership). */
[data-room="dystopian"] .dy-readout {
  font-family: var(--syn-mono);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--syn-text);
  background: #070809;
  background-image: repeating-linear-gradient(180deg, transparent 0 2px, rgba(0, 0, 0, .18) 2px 3px);
  border-top: 1px solid var(--syn-border);
  border-bottom: 1px solid var(--syn-border);
  box-shadow: inset 0 0 40px rgba(0, 196, 55, .06);
  padding: .9rem 1.1rem;
  margin: 0 0 1.4rem;
  display: grid;
  gap: .25rem;
}
[data-room="dystopian"] .dy-readout-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .4em 1.2em;
}
[data-room="dystopian"] .dy-readout-key {
  color: var(--dy-phos);
  letter-spacing: .16em;
  font-size: var(--t-2xs);
  min-width: 5.5em;
  text-shadow: 0 0 5px rgba(0, 196, 55, .45);
}
[data-room="dystopian"] .dy-readout-val { color: var(--syn-text); }
[data-room="dystopian"] .dy-readout-dim { color: var(--syn-text-mute); }
[data-room="dystopian"] .dy-readout-line--log .dy-readout-val { color: var(--syn-text-dim); }
[data-room="dystopian"] .dy-readout-line--prompt { margin-top: .3rem; }
[data-room="dystopian"] .dy-readout-caret {
  display: inline-block;
  width: .55em;
  height: 1em;
  margin-left: .25em;
  background: var(--dy-phos);
  animation: dy-caret calc(var(--dystopian-spd) * 0.18) steps(1, end) infinite;
}

/* The week as a seven-slot buffer: the house strip, box-drawn.

   THE BUFFER IS THE SCREEN'S WIDTH, not the house's. It was max-width 560px
   — the house's own measure, carried in rather than chosen — while the
   readout band above it and every reading below it run the screen's full
   648px. A console prints every line from the same column; a strip inset
   44px inside that column is not a narrower object, it is the same object
   in the wrong place.

   And the rule is drawn TO the buffer. The box characters are a fixed
   count, so they were only ever right at one window: 44 of them measure
   450px, which left a quarter of a 560px buffer with no rule under it on a
   desk and overflowed a phone. The corners are now their own characters at
   the two ends and the run between them is clipped to whatever is left, so
   the box closes at every width. .dy-buffer, .dy-buffer-rule and
   .dy-buffer-run exist in no other room and nowhere in the site sheet, so
   they are the Terminal's own furniture and may be laid out freely (Rule I
   is ownership). */
[data-room="dystopian"] .dy-buffer { margin: 0 auto 1.4rem; max-width: 100%; }
[data-room="dystopian"] .dy-buffer-rule {
  font-family: var(--syn-mono);
  font-size: var(--t-2xs);
  color: var(--syn-text-mute);
  white-space: pre;
  overflow: hidden;
  line-height: 1;
  display: flex;
}
[data-room="dystopian"] .dy-buffer-run {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
}

/* ======================================================================
   ONE SCREEN, ONE MEASURE — the only place Rule I lets a room move the
   site's own furniture, and the reason the rule has that exception.

   Everything this machine prints starts at the same column. The readout at
   the head of the page and the seven readings under it both run the
   screen's full 648px; the house draws the hour panel, the week, the
   correspondences, the card of the day, the season line and the page's
   whole foot at a max-width of 560px, so each of them came out inset 44px
   on both sides. Two margins on one screen.

   The brief for this repair recorded the Terminal's column as 451→974 and
   its blocks as WIDER than it. That figure is not a column: it is the text
   inside .syn-horo-hour's own 1.1rem padding and 1px border (560 − 2×18.6
   = 523), which is what a probe hunting for the first paragraph on the page
   finds when a room has replaced the head with a readout that contains no
   paragraph at all. The Terminal's column is 389→1037, the screen, and its
   blocks are narrower than it exactly as in every other room — measured,
   not assumed.

   These blocks KEEP their padding. This room leaves the house's panels as
   panels — a console shows a bordered field, and nothing here takes their
   border, fill or radius away — so the padding is the field's own and is
   still what holds the text off its edge.

   600px is where it starts to matter and is therefore where it is fixed:
   the screen is wider than 560px only above 592px of viewport.
   ====================================================================== */
@media (min-width: 600px) {
  [data-room="dystopian"] .syn-horo-hour,
  [data-room="dystopian"] .syn-harmony,
  [data-room="dystopian"] .syn-week,
  [data-room="dystopian"] .syn-corr,
  [data-room="dystopian"] .syn-yours,
  [data-room="dystopian"] .syn-season-line,
  [data-room="dystopian"] .syn-wheelyear,
  [data-room="dystopian"] .syn-letter,
  [data-room="dystopian"] .syn-horo-chartlink {
    max-width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-room="dystopian"] .dy-readout-caret { animation: none !important; opacity: 1 !important; }
}

/* ======================================================================
   THE OWNED PAGES, II — five more surfaces the console prints itself.

   Every class below is `.dy-*`. None of them appears in any site
   stylesheet or in any page's own <style> block, so they are the
   Terminal's own furniture and may be laid out freely: Rule I is
   ownership, not property.

   One shared idiom holds the five together, because a console has one:
   a COMMAND LINE the machine echoed, then its OUTPUT in rows of
   key-and-value, on a panel darker than the concrete behind it, with the
   character cell's own scan across it. Keys are phosphor, values are the
   room's own text ink, and nothing here is set in --syn-text-mute: on the
   board-formed ground that measures 2.81:1, which is under the body floor.
   The panels are #070809, where the same inks measure 8.5:1 and 10.1:1.
   ====================================================================== */

/* The recipe every panel below is cut from — one declaration, five uses. */
[data-room="dystopian"] .dy-man,
[data-room="dystopian"] .dy-fault,
[data-room="dystopian"] .dy-vol,
[data-room="dystopian"] .dy-mon,
[data-room="dystopian"] .dy-panel {
  font-family: var(--syn-mono);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--syn-text);
  background-color: #070809;
  background-image: repeating-linear-gradient(180deg,
    transparent 0 2px, rgba(0, 0, 0, .18) 2px 3px);
  border-top: 1px solid var(--syn-border);
  border-bottom: 1px solid var(--syn-border);
  box-shadow: inset 0 0 40px rgba(0, 196, 55, .06);
}

/* The echoed command. Dim, because the machine is quoting itself. */
[data-room="dystopian"] .dy-man-h,
[data-room="dystopian"] .dy-vol-cmd,
[data-room="dystopian"] .dy-mon-cmd,
[data-room="dystopian"] .dy-panel-cmd {
  font-size: var(--t-2xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dy-phos);
  text-shadow: 0 0 5px rgba(0, 196, 55, .45);
}
[data-room="dystopian"] .dy-vol-cmd,
[data-room="dystopian"] .dy-mon-cmd,
[data-room="dystopian"] .dy-panel-cmd {
  text-transform: none;
  letter-spacing: .04em;
  color: var(--syn-text-dim);
  text-shadow: none;
}

/* A block cursor, everywhere one belongs. */
[data-room="dystopian"] .dy-fault-caret,
[data-room="dystopian"] .dy-vol-caret {
  background: var(--dy-phos);
  animation: dy-caret calc(var(--dystopian-spd) * 0.18) steps(1, end) infinite;
}

/* ── SYNCRETICON(7) — the legal shelf as a manual page ─────────────────
   templates/rooms/dystopian/legal/_base.html. Help/FAQ, About, Privacy,
   Terms and Contact all share one base, so one file makes five manual
   entries. The 720px measure is the house article's own, so the head
   rule, the section labels and the prose stand in one column rather than
   the furniture running the screen and the text running narrower. */
[data-room="dystopian"] .dy-man {
  max-width: var(--measure-document);
  margin: 1.8rem auto 0;
  padding: .8rem 1rem .9rem;
}
[data-room="dystopian"] .dy-man--foot { margin: 0 auto 3rem; }
[data-room="dystopian"] .dy-man-rule {
  display: flex;
  align-items: center;
  gap: .7em;
  margin: 0 0 .9rem;
  font-size: var(--t-2xs);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dy-phos);
}
[data-room="dystopian"] .dy-man--foot .dy-man-rule { margin: .9rem 0 0; }
[data-room="dystopian"] .dy-man-rule-end { white-space: nowrap; }
[data-room="dystopian"] .dy-man-rule-mid {
  white-space: nowrap;
  color: var(--syn-text-dim);
}
/* The rule between the three labels is drawn, not typed: a run of box
   characters is only ever the right length at one window, which is the
   lesson .dy-buffer-run already paid for on the week strip. */
/* On a narrow screen there is no leftover width to draw a rule IN, and a
   1px run four pixels long reads as a hyphen stuck to the word before it.
   A real manual head on a narrow terminal has no rule either — it is three
   labels separated by spaces — so the run is a plain spacer until there is
   room for a line, and the line appears with the room. */
[data-room="dystopian"] .dy-man-rule-run {
  flex: 1 1 0;
  min-width: 0;
  height: 0;
  border-top: 0;
}
[data-room="dystopian"] .dy-man-h {
  margin: 1.1rem 0 .3rem;
  border-bottom: 1px solid rgba(0, 196, 55, .22);
  padding-bottom: .2rem;
}
[data-room="dystopian"] .dy-man-h:first-of-type { margin-top: 0; }
[data-room="dystopian"] .dy-man-b {
  margin: 0;
  padding-left: 2.5ch;
  color: var(--syn-text);
}
[data-room="dystopian"] .dy-man-b--cmd { color: var(--dy-phos); }
[data-room="dystopian"] .dy-man-b--cmd i { color: var(--syn-text-dim); font-style: normal; }
[data-room="dystopian"] .dy-man-name {
  color: var(--dy-phos);
  font-weight: 600;
  letter-spacing: .04em;
}
[data-room="dystopian"] .dy-man-note { color: var(--syn-text-dim); }
[data-room="dystopian"] .dy-man-ref {
  color: var(--syn-gold-hi);
  text-decoration: underline;
  text-decoration-color: rgba(0, 196, 55, .45);
  text-underline-offset: .2em;
}
[data-room="dystopian"] .dy-man-ref:hover { text-decoration-color: var(--syn-gold-hi); }
/* SEE ALSO is a LIST of entries and needs a gap between them; the same class
   used inline inside a sentence must not carry one, or the reference sits a
   character and a half away from the comma that follows it and reads as a
   typo. So the gap belongs to the foot, not to the class. */
[data-room="dystopian"] .dy-man--foot .dy-man-ref {
  display: inline-block;
  margin-right: 1.6ch;
}

/* And the article between them is set as the manual it now sits inside.
   Chrome only — type, ink and a rule. No geometry on a site selector
   outside a min-width block (Rule I), so the house measure, margins and
   padding are left exactly as the house set them. */
[data-room="dystopian"] .legal-page h2 {
  font-family: var(--syn-mono);
  font-size: var(--t-sm);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dy-phos);
  text-shadow: 0 0 5px rgba(0, 196, 55, .35);
  border-bottom: 1px solid rgba(0, 196, 55, .22);
}
[data-room="dystopian"] .legal-page h3 {
  font-family: var(--syn-mono);
  letter-spacing: .06em;
  color: var(--syn-text);
}
[data-room="dystopian"] .legal-page .legal-sub {
  color: var(--syn-text-dim);
  letter-spacing: .04em;
  border-bottom-color: rgba(0, 196, 55, .22);
}
[data-room="dystopian"] .legal-page .legal-meta {
  color: var(--syn-text-dim);
  border-top-color: rgba(0, 196, 55, .22);
}
[data-room="dystopian"] .legal-page blockquote {
  border-left-color: rgba(0, 196, 55, .40);
  color: var(--syn-text);
  font-style: normal;
}

/* ── THE FAULT — templates/rooms/dystopian/404.html ────────────────────
   Not a decorated apology. The address that failed, a code, a stamp, and
   the state of the process that refused it. The house error section, with
   its <h1> and its way back, follows underneath. */
[data-room="dystopian"] .dy-fault {
  /* The error page's own measure, so the report and the numeral under it
     are one column. */
  max-width: var(--measure-statement);
  margin: 1.6rem auto 0;
  padding: .85rem 1.1rem .7rem;
}
/* The box is drawn in ONE material. It was a corner GLYPH either side of a
   CSS border, and those two are placed by different systems — the glyph's
   stroke sits where the font puts it, the border sits on the flex line box —
   so the rule met the corner at neither end, at any width, and a flex `gap`
   opened a second hole beside the first. A box of characters drawn in the
   same face at the same size closes, because every stroke is the same
   stroke. This is the lesson .dy-buffer-run already paid for on the week
   strip; the run is clipped to the width that is left. */
[data-room="dystopian"] .dy-fault-rule {
  display: flex;
  align-items: baseline;
  margin: 0 0 .6rem;
  font-family: var(--syn-mono);
  font-size: var(--t-2xs);
  line-height: 1;
  white-space: pre;
  overflow: hidden;
  color: var(--dy-alarm);
}
[data-room="dystopian"] .dy-fault-rule:last-of-type { margin: .6rem 0 0; }
[data-room="dystopian"] .dy-fault-run {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
}
[data-room="dystopian"] .dy-fault-tag {
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--syn-warn);
  flex: 0 0 auto;
}
[data-room="dystopian"] .dy-fault-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3em 1.1em;
}
[data-room="dystopian"] .dy-fault-key,
[data-room="dystopian"] .dy-vol-dim,
[data-room="dystopian"] .dy-mon-k,
[data-room="dystopian"] .dy-par-k {
  font-size: var(--t-2xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dy-phos);
  text-shadow: 0 0 5px rgba(0, 196, 55, .45);
}
[data-room="dystopian"] .dy-fault-key { min-width: 7em; }
[data-room="dystopian"] .dy-fault-val { color: var(--syn-text); }
/* The one thing on the page that is genuinely wrong reads as wrong. */
[data-room="dystopian"] .dy-fault-val--alarm {
  color: var(--syn-warn);
  letter-spacing: .1em;
}
[data-room="dystopian"] .dy-fault-val--path {
  color: var(--syn-gold-hi);
  word-break: break-all;
}
[data-room="dystopian"] .dy-fault-prompt {
  display: flex;
  align-items: center;
  gap: .4em;
  margin: .5rem 0 0;
}
[data-room="dystopian"] .dy-fault-caret {
  display: inline-block;
  width: .55em;
  height: 1em;
}

/* ── THE MOUNTED VOLUME — oracle/reference_index.html ──────────────────
   909 records on 23 shelves, and the house draws them as illustrated
   cards you scroll. The index to them is one line each, so the whole
   collection is on a screen before the pictures start. */
[data-room="dystopian"] .dy-vol {
  /* One measure: the same width as the reference index it lists, read from the page's own
     token so the two columns cannot drift apart. */
  max-width: var(--measure-index);
  margin: 0 auto 1.6rem;
  padding: .85rem 1.1rem .8rem;
}
[data-room="dystopian"] .dy-vol-cmd,
[data-room="dystopian"] .dy-vol-out,
[data-room="dystopian"] .dy-vol-dir { margin: 0; }
[data-room="dystopian"] .dy-vol-cmd { margin-top: .9rem; }
[data-room="dystopian"] .dy-vol-cmd:first-child { margin-top: 0; }
[data-room="dystopian"] .dy-vol-out { color: var(--syn-text); }
[data-room="dystopian"] .dy-vol-num {
  color: var(--dy-phos);
  text-shadow: 0 0 5px rgba(0, 196, 55, .45);
}
[data-room="dystopian"] .dy-vol-dir {
  margin-top: .8rem;
  color: var(--syn-gold-hi);
  letter-spacing: .04em;
}
[data-room="dystopian"] .dy-vol-out--total {
  margin-top: .8rem;
  border-top: 1px solid rgba(0, 196, 55, .22);
  padding-top: .35rem;
  color: var(--syn-text-dim);
}
[data-room="dystopian"] .dy-vol-prompt {
  display: flex;
  align-items: center;
  gap: .4em;
  margin: .4rem 0 0;
}
[data-room="dystopian"] .dy-vol-caret {
  display: inline-block;
  width: .55em;
  height: 1em;
}
[data-room="dystopian"] .dy-dir {
  list-style: none;
  margin: .15rem 0 0;
  padding: 0;
}
/* Mobile first: the record count, the name and what is on the shelf. The
   permission bits are the first thing a narrow screen can lose and the
   first thing a wide one should show. */
[data-room="dystopian"] .dy-dir-row {
  display: grid;
  grid-template-columns: 3.5ch minmax(0, 1fr);
  align-items: baseline;
  gap: 0 1ch;
  padding: .06rem 0;
}
[data-room="dystopian"] .dy-dir-mode { display: none; }
[data-room="dystopian"] .dy-dir-size {
  color: var(--dy-phos);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
[data-room="dystopian"] .dy-dir-name {
  color: var(--syn-text);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
[data-room="dystopian"] .dy-dir-name:hover {
  color: var(--syn-gold-hi);
  border-bottom-color: var(--syn-gold-hi);
}
[data-room="dystopian"] .dy-dir-note {
  grid-column: 2;
  color: var(--syn-text-dim);
  font-size: var(--t-2xs);
}
[data-room="dystopian"] .dy-dir-row:hover { background-color: rgba(0, 196, 55, .06); }

/* ── THE MONITOR — oracle/readings.html ────────────────────────────────
   Two buses: D turns at midnight, H at the planetary hour. Each row is a
   channel — number, lamp, source, what is on it, and the stamp. */
[data-room="dystopian"] .dy-mon {
  /* One measure: the same width as the readings board it indexes, read from the page's own
     token so the two columns cannot drift apart. */
  max-width: var(--measure-board);
  margin: 0 auto 1.6rem;
  padding: .85rem 1.1rem .8rem;
}
[data-room="dystopian"] .dy-mon-cmd { margin: 0 0 .6rem; }
[data-room="dystopian"] .dy-mon-head {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem 1.6rem;
  border-top: 1px solid rgba(0, 196, 55, .22);
  border-bottom: 1px solid rgba(0, 196, 55, .22);
  padding: .4rem 0;
}
[data-room="dystopian"] .dy-mon-head-cell {
  display: flex;
  align-items: baseline;
  gap: .6ch;
}
[data-room="dystopian"] .dy-mon-v { color: var(--syn-text); }
[data-room="dystopian"] .dy-mon-list {
  list-style: none;
  margin: .5rem 0 0;
  padding: 0;
}
[data-room="dystopian"] .dy-mon-row {
  display: grid;
  grid-template-columns: 3.5ch .5em minmax(0, 1fr);
  align-items: baseline;
  gap: .1rem 1ch;
  padding: .18rem 0;
  border-bottom: 1px solid rgba(0, 196, 55, .10);
}
[data-room="dystopian"] .dy-mon-ch {
  grid-row: span 2;
  color: var(--dy-phos);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 5px rgba(0, 196, 55, .45);
}
[data-room="dystopian"] .dy-mon-lamp {
  grid-row: span 2;
  width: .45em;
  height: .45em;
  border-radius: 50%;
  background: var(--dy-phos);
  box-shadow: 0 0 7px var(--dy-phos);
  animation: dy-lamp calc(var(--dystopian-spd) * 0.9) steps(1, end) infinite;
}
/* The hour bus is the one that is about to be rewritten, so its lamps run
   on the warning colour rather than the steady phosphor. */
[data-room="dystopian"] .dy-mon-row--hour .dy-mon-lamp {
  background: var(--syn-warn);
  box-shadow: 0 0 7px var(--syn-warn);
}
[data-room="dystopian"] .dy-mon-row--hour .dy-mon-ch { color: var(--syn-warn); text-shadow: none; }
[data-room="dystopian"] .dy-mon-src {
  grid-column: 3;
  font-size: var(--t-2xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--syn-text-dim);
}
[data-room="dystopian"] .dy-mon-sig {
  grid-column: 3;
  color: var(--syn-text);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
[data-room="dystopian"] .dy-mon-sig:hover {
  color: var(--syn-gold-hi);
  border-bottom-color: var(--syn-gold-hi);
}
[data-room="dystopian"] .dy-mon-t {
  grid-column: 3;
  font-size: var(--t-2xs);
  color: var(--syn-text-dim);
  font-variant-numeric: tabular-nums;
}
[data-room="dystopian"] .dy-mon-dead {
  margin: .8rem 0;
  letter-spacing: .2em;
  color: var(--syn-warn);
}
[data-room="dystopian"] .dy-mon-foot {
  margin: .7rem 0 0;
  border-top: 1px solid rgba(0, 196, 55, .22);
  padding-top: .35rem;
  font-size: var(--t-2xs);
  letter-spacing: .12em;
  color: var(--syn-text-dim);
}

/* ── THE CONTROL PANEL — accounts/portal.html ──────────────────────────
   The machine reporting its own configuration: one parameter a row, the
   value it currently holds, and the switch that sets it. */
[data-room="dystopian"] .dy-panel {
  /* One measure: the same width as the portal grid it reports on, read from the page's own
     token so the two columns cannot drift apart. */
  max-width: var(--measure-grid);
  margin: 0 auto 1.6rem;
  padding: .85rem 1.1rem .8rem;
}
[data-room="dystopian"] .dy-panel-cmd { margin: 0; }
[data-room="dystopian"] .dy-panel-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: .6rem 0;
}
[data-room="dystopian"] .dy-par {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1.2em;
  padding: .25rem 0;
  border-bottom: 1px solid rgba(0, 196, 55, .10);
}
[data-room="dystopian"] .dy-par-k { margin: 0; }
[data-room="dystopian"] .dy-par-v {
  margin: 0;
  color: var(--syn-text);
}
[data-room="dystopian"] .dy-par-on {
  color: var(--dy-phos);
  letter-spacing: .1em;
  text-shadow: 0 0 6px rgba(0, 196, 55, .5);
}
[data-room="dystopian"] .dy-par-warn {
  color: var(--syn-warn);
  letter-spacing: .1em;
}
[data-room="dystopian"] .dy-par-dim { color: var(--syn-text-dim); }
[data-room="dystopian"] .dy-par-set {
  margin-left: .8ch;
  font-size: var(--t-2xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--syn-gold-hi);
  text-decoration: underline;
  text-decoration-color: rgba(0, 196, 55, .45);
  text-underline-offset: .25em;
}
[data-room="dystopian"] .dy-par-set:hover { text-decoration-color: var(--syn-gold-hi); }

/* A console has room for two columns once there is one. Mobile first
   above; this is the only widening. */
@media (min-width: 600px) {
  [data-room="dystopian"] .dy-dir-row {
    grid-template-columns: 11ch 4.5ch minmax(9ch, 18ch) minmax(0, 1fr);
  }
  [data-room="dystopian"] .dy-dir-mode {
    display: block;
    color: var(--syn-text-dim);
  }
  [data-room="dystopian"] .dy-dir-note { grid-column: 4; }
  [data-room="dystopian"] .dy-mon-row {
    /* The source names are set uppercase with .16em of tracking, so a column
       sized by raw character count wraps two thirds of them: 24ch of advance
       is what "ASTRAL & CONSCIOUSNESS" actually occupies. One channel, one
       line, which is the whole point of a monitor. */
    grid-template-columns: 3.5ch .5em minmax(12ch, 24ch) minmax(0, 1fr) max-content;
  }
  [data-room="dystopian"] .dy-mon-ch,
  [data-room="dystopian"] .dy-mon-lamp { grid-row: auto; }
  [data-room="dystopian"] .dy-mon-src { grid-column: 3; }
  [data-room="dystopian"] .dy-mon-sig { grid-column: 4; }
  [data-room="dystopian"] .dy-mon-t   { grid-column: 5; }
  [data-room="dystopian"] .dy-par { grid-template-columns: 12em minmax(0, 1fr); }
  [data-room="dystopian"] .dy-man-rule-run {
    min-width: .6rem;
    border-top: 1px solid rgba(0, 196, 55, .32);
  }
}

/* Rule VI — every animated selector above, switched off for a reader who
   asked for stillness. !important because the state variants out-specify
   a bare rule. */
@media (prefers-reduced-motion: reduce) {
  [data-room="dystopian"] .dy-fault-caret,
  [data-room="dystopian"] .dy-vol-caret { animation: none !important; opacity: 1 !important; }
  [data-room="dystopian"] .dy-mon-lamp { animation: none !important; opacity: 1 !important; }
}

/* ── THE LIT CONTROL ───────────────────────────────────────────────────
   The rack steel above is laid on EVERY .syn-btn, and `background-image`
   out-specifies the `background:` SHORTHAND that fills the primary button
   with the room's gold — the same shorthand hazard that greyed out the
   planet stripe on .syn-23-section, in the other direction. So the site's
   main call to action came out --syn-on-gold (#050706) on rack steel:
   measured 1.36:1 on the error page's "Begin again", which is the one
   button on a page a lost reader has. The danger button loses --syn-mars
   the same way, and that one is correspondence.

   No colour is written here. The image layer is removed so the token
   underneath shows through, which puts the primary back at 8.6:1 and
   returns Mars to Mars. A control that is live in this room is a control
   that is LIT, so a phosphor-filled button is also the right answer for
   the premise and not only for the floor. */
[data-room="dystopian"] .syn-btn-primary,
[data-room="dystopian"] .syn-btn-danger {
  background-image: none;
}

/* ── ONE MUTE THAT IS TOO MUTE ON A CARD ───────────────────────────────
   Found by the rendered audit on /readings/, which this room now owns.
   `--syn-text-mute` is measured by scripts/check_rooms.py against the
   room's GROUND, where it is 3.05:1 and passes. The teaching card's tag
   sits on `--syn-surface` (#111315), a lighter surface than the ground,
   and there the same ink measures 2.87:1 — under the body floor, on 31
   lines of the page, in the site's default theme.

   The real repair is the token, and the token is generated into
   syncreticon.css from `oracle/rooms.py`, which this work may not touch.
   This is therefore the room doing what a room may do: the same role,
   one step brighter, at 5.29:1 on the card. Nothing else about the tag
   moves — it is still the faintest thing on the card. */
[data-room="dystopian"] .syn-teaching-discipline-tag { color: var(--syn-text-dim); }
