:root {
  color-scheme: dark;

  /*
    Cassette futurism, rendered as software rather than as furniture.

    The seven colours below are the identity palette. The three named dark
    grounds immediately after them are the OS display surfaces specified by
    docs/omnipug-os-design-system.md. Everything else is a role that points at
    those values, or a straight lightening/darkening of one.

    The one structural change from the previous pass: the UI is a screen, not
    a printed sheet, so the surfaces are dark and the ink ladder runs upward
    into the light instead of down into it.
  */
  --hull-graphite: #2E3136;
  --oxidized-olive: #4A5248;
  --aged-steel: #6E6558;
  --signal-amber: #C97A3D;
  --warm-fluorescent: #E3D8BF;
  --terminal-green: #7FAE9B;
  --rust-red: #8B4438;

  /* Named dark grounds from the Omnipug OS specification. */
  --desktop-dark: #202228;
  --window-dark: #25282D;
  --console-dark: #161B19;

  /*
    Derived greys. A window sitting on a desktop sitting on a room needs more
    steps than the palette names, so Hull Graphite is moved along its own value
    axis in both directions and nothing else changes.
  */
  --graphite-deep: #1B1D20;
  --graphite-raised: #3A3E44;
  --olive-deep: #3C443B;

  /*
    Surfaces, darkest to lightest. Four is the whole set: a fifth step stops
    being legible as depth and starts reading as a colour mistake.

      --screen          the desktop ground, behind everything
      --surface-sunken  wells that recede: inputs, code, secondary panes
      --surface         the standard window body
      --surface-raised  things that sit on a window: rows, buttons, keys
  */
  --screen: var(--desktop-dark);
  --surface-sunken: var(--window-dark);
  --surface: var(--hull-graphite);
  --surface-raised: var(--graphite-raised);

  /* Console ground: near-black, pulled green so phosphor sits in it. */
  --console: var(--console-dark);

  /*
    Text on --surface, in three steps. Measured, not estimated:

      --ink       9.23  headings, strong, anything that must land first
      --ink-soft  7.82  body copy
      --ink-dim   5.48  meta, labels, small print, inactive titles

    All three clear AA at any size, and they hold up on --surface-raised too,
    where the ladder compresses to 7.60 / 6.45 / 4.52.

    --ink-dim is Aged Steel *lightened*. The obvious move is to use Aged Steel
    itself as the muted ink, and it is what the brief suggests, but on this
    ground it measures 2.28: below AA and below even the 3:1 floor for large
    text. It is a furniture colour, and it does not become a text colour by
    being asked to.
  */
  --ink: var(--warm-fluorescent);
  --ink-soft: #D7C7A3;
  --ink-dim: #AFA79B;

  /*
    Edges. Borders are 1px and hard; depth comes from the relief pair below,
    not from blur.

      --edge         the resting border, Aged Steel as the brief specifies
      --edge-strong  focus and hover, lightened to clear 3:1 (WCAG 1.4.11)
      --edge-soft    hairlines *inside* a window, where a full edge is noise
  */
  --edge: var(--aged-steel);
  --edge-strong: #857A6A;
  --edge-soft: #575046;

  /*
    Early-GUI relief: one light line top/left, one dark line bottom/right.
    Kept to a single pixel and low opacity — the moment it is legible as a
    bevel it stops being an operating system and becomes a machine panel.
  */
  --relief-light: rgba(227, 216, 191, .09);
  --relief-dark: rgba(14, 15, 18, .55);
  --shadow: rgba(12, 13, 16, .55);

  /*
    --accent is the only colour allowed to say "here": active window, current
    item, focus, selection. At 3.94 on --surface Signal Amber is a fill and
    not a word, so text that needs to be amber uses --accent-lit, the same
    signal lightened until it reads (5.53 on --surface, 6.26 on a sunken one).

    --alert is error and destruction only — not a second accent, and not the
    colour of section labels, which is what it had drifted into. Rust Red is
    1.85 on --surface, so it marks with a block or a bar; --alert-lit is the
    variant that can carry the words.
  */
  --accent: var(--signal-amber);
  --accent-lit: #DE9A5F;
  --alert: var(--rust-red);
  --alert-lit: #D39C93;
  --phosphor: var(--terminal-green);

  --topbar-h: 30px;
  --dock-h: 44px;
  --radius: 0;

  /* One short vertical rhythm; the numbered aliases keep existing modules stable. */
  --space-micro: 4px;
  --space-small: 8px;
  --space-compact: 12px;
  --space-normal: 16px;
  --space-section: 24px;
  --space-1: var(--space-micro);
  --space-2: var(--space-micro);
  --space-3: var(--space-small);
  --space-4: var(--space-small);
  --space-5: var(--space-compact);
  --space-6: var(--space-normal);
  --space-7: var(--space-section);
  --space-8: calc(var(--space-section) + var(--space-small));

  /* Hard software edges and the two divider strengths used inside modules. */
  --stroke-hairline: 1px;
  --stroke-active: 2px;
  --divider-subtle: var(--stroke-hairline) solid rgba(110, 101, 88, .45);
  --divider-strong: var(--stroke-hairline) solid var(--aged-steel);

  /* Mechanical feedback stays inside the 100–180ms range from the spec. */
  --motion-fast: 100ms;
  --motion-standard: 140ms;
  --motion-slow: 180ms;
  --ease-mechanical: cubic-bezier(.2, 0, 0, 1);

  --focus-width: var(--stroke-active);
  --focus-offset: 2px;
  --focus-color: var(--accent);

  --font-brand: "Oxanium", system-ui, sans-serif;
  --font-ui: "IBM Plex Sans", system-ui, sans-serif;
  --font-content: "IBM Plex Sans", Arial, sans-serif;
  --font-terminal: "IBM Plex Mono", "Courier New", ui-monospace, monospace;

  --text-meta: .75rem;
  --text-ui: .8125rem;
  --text-body: 1rem;
  --text-title: 1.125rem;
  --leading-tight: 1.15;
  --leading-ui: 1.3;
  --leading-body: 1.55;
  --tracking-title: .06em;
  --tracking-meta: .08em;

  /* Safe defaults for data-driven Phase 4 primitives. */
  --rail-start: 0;
  --rail-span: 1;
  --analyzer-value: 0;
  --band: 0;
}

* {
  box-sizing: border-box;
}

html,
body {
  scrollbar-width: thin;
  scrollbar-color: var(--edge) var(--surface-sunken);
  width: 100%;
  min-width: 320px;
  height: 100%;
  margin: 0;
}

body {
  overflow: hidden;
  /* Shows through before a room wallpaper paints, and in the letterbox. */
  background: var(--screen);
  color: var(--ink);
  font-family: var(--font-content);
  font-size: 16px;
  line-height: 1.55;
  text-rendering: optimizeLegibility;
}

button,
input,
textarea {
  font: inherit;
}

button {
  color: inherit;
}

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

/* Typography roles for later OS modules; content meaning stays in the HTML. */
.os-type-title {
  font-family: var(--font-brand);
  font-size: var(--text-title);
  font-weight: 600;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-title);
  text-transform: uppercase;
}

.os-type-ui {
  font-family: var(--font-ui);
  font-size: var(--text-ui);
  font-weight: 500;
  line-height: var(--leading-ui);
}

.os-type-body {
  font-family: var(--font-content);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.os-type-meta {
  font-family: var(--font-terminal);
  font-size: var(--text-meta);
  line-height: var(--leading-ui);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}

.os-shell {
  position: relative;
  width: 100vw;
  height: 100dvh;
  overflow: hidden;
  background: var(--screen);
}

.topbar,
.dock {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  color: var(--ink);
  font-family: var(--font-ui);
}

.topbar {
  top: 0;
  height: var(--topbar-h);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  padding: 0 8px;
  border-bottom: 1px solid var(--edge-soft);
  background: var(--screen);
}

.dock {
  bottom: 0;
  height: var(--dock-h);
  gap: 8px;
  padding: 5px 8px;
  border-top: 1px solid var(--edge-soft);
  background: var(--screen);
}

.brand-chip,
.dock__home,
.dock__task {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 26px;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    border-color var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical),
    transform var(--motion-fast) var(--ease-mechanical);
}

.brand-chip {
  padding: 1px 6px 1px 2px;
  color: var(--ink);
}

.brand-chip span:last-child,
.dock__home span:last-child {
  font-family: var(--font-brand);
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .04em;
}

/*
  The emblem is a pure black silhouette on transparency, so it is painted as a
  mask rather than placed as an image: on the near-black topbar the artwork's
  own colour would be invisible, and masking is what lets one file take an
  exact palette colour instead of whatever a filter chain lands on.

  It is decorative — both slots already label themselves in text beside it —
  which is why losing the <img> costs nothing.
*/
.brand-chip__sigil {
  display: inline-block;
  width: 22px;
  height: 22px;
  background: var(--warm-fluorescent);
  -webkit-mask: url("./assets/mascot/pug-emblem.png") center / contain no-repeat;
  mask: url("./assets/mascot/pug-emblem.png") center / contain no-repeat;
}

.brand-chip:hover,
.dock__home:hover {
  background: var(--surface);
  border-color: var(--edge-soft);
}

.topbar__module {
  min-width: 0;
  justify-self: center;
  padding: 0 var(--space-5);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
  letter-spacing: var(--tracking-meta);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar__status {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-terminal);
  font-size: 11px;
  letter-spacing: .04em;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-dim);
}

.status-pill::before {
  content: "";
  width: 5px;
  height: 5px;
  background: var(--phosphor);
}

#clock {
  min-width: 42px;
  text-align: right;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.desktop {
  position: absolute;
  inset: var(--topbar-h) 0 var(--dock-h);
  overflow: hidden;
  isolation: isolate;
}

.desktop::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -3;
  background:
    repeating-linear-gradient(
      0deg,
      transparent 0,
      transparent 61px,
      rgba(27,29,32,.28) 61px,
      rgba(27,29,32,.28) 64px
    ),
    repeating-linear-gradient(
      90deg,
      transparent 0,
      transparent 67px,
      rgba(27,29,32,.22) 67px,
      rgba(27,29,32,.22) 70px
    );
  opacity: .56;
  pointer-events: none;
}

/*
  Sits behind the room layer, so it is normally covered. It is visible for the
  220ms of a room crossfade, when both wallpapers are part-transparent, and
  before the first one paints — which is exactly why it has to be in the room's
  own palette. In arcane blue it read as a violet flash every time the lift
  moved.
*/
.desktop::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    linear-gradient(90deg, rgba(46,49,54,.24) 0%, rgba(46,49,54,.14) 30%, rgba(46,49,54,.06) 56%, transparent 76%),
    radial-gradient(circle at 17% 75%, rgba(74,82,72,.14), transparent 18%),
    radial-gradient(circle at 76% 22%, rgba(201,122,61,.1), transparent 14%);
  pointer-events: none;
}

.room-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.room-wallpapers,
.room-wallpaper,
.room-overlay,
.room-hotspots {
  position: absolute;
  inset: 0;
}

.room-wallpapers,
.room-overlay {
  pointer-events: none;
}

/*
  The bunker paintings arrive already graded in the palette — graphite, olive,
  aged steel — so they are left close to how they were exported. The old
  saturation push existed to make flat fantasy art carry; applied here it
  turns worn amber into orange plastic.
*/
.room-wallpaper {
  opacity: 0;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
  filter: saturate(1.04) contrast(1.04);
  transition: opacity 220ms ease-out;
}

.room-wallpaper.is-active {
  opacity: 1;
}

/*
  A hard cut, not a faster fade. The navigation does not wait for a transition
  under reduced motion, so leaving one running here would let the outgoing
  room be dropped mid-fade and put back the grey dip the stacking order exists
  to avoid.
*/
@media (prefers-reduced-motion: reduce) {
  .room-wallpaper {
    transition: none;
  }
}

/*
  The room tint. Graphite cools the corners the fittings do not reach and a
  thin amber pass sits where the working light is, so the frame reads as one
  space lit from a few points rather than as an evenly exposed photograph.
*/
.room-overlay {
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(227,216,191,.04), transparent 20%),
    radial-gradient(circle at 74% 40%, rgba(201,122,61,.1), transparent 22%),
    linear-gradient(90deg, rgba(46,49,54,.2), rgba(46,49,54,.08) 34%, transparent 62%),
    linear-gradient(90deg, rgba(46,49,54,.08) 0%, transparent 30%, transparent 64%, rgba(46,49,54,.18) 100%);
}

/*
  Ambient light.

  Every room runs off the same tired generator, and mains that old do not hold
  a steady level. This is a single soft wash over the whole frame whose
  brightness drifts, so the room reads as lit by a supply under load without
  any object in the painting appearing to move.

  It is deliberately whole-frame rather than aimed at a fitting. A pool of
  light that pulses in one spot needs to sit on the thing producing it, and
  that needs per-room coordinates; this layer knows nothing about which room
  is on screen.
*/
.room-overlay::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      ellipse at 50% 45%,
      rgba(227,216,191,.07),
      rgba(201,122,61,.028) 55%,
      transparent 78%
    );
  will-change: opacity, transform;
  animation: room-breathe 11s ease-in-out infinite;
}

/*
  The steps are deliberately uneven. A symmetrical cycle reads as a signal
  generator; a loaded circuit never comes back to the same level on the same
  beat. The scale is what widens and narrows the falloff, so the light spreads
  a little as it brightens instead of only changing level.
*/
@keyframes room-breathe {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  19% {
    opacity: .52;
    transform: scale(.97);
  }
  37% {
    opacity: .84;
    transform: scale(1.04);
  }
  58% {
    opacity: .28;
    transform: scale(.955);
  }
  81% {
    opacity: .74;
    transform: scale(1.03);
  }
}

/*
  Reduced motion keeps the light and drops the movement. Removing the wash
  instead would leave every room slightly colder than it was designed to be.
*/
@media (prefers-reduced-motion: reduce) {
  .room-overlay::after {
    animation: none;
  }
}

/*
  Fittings: fluorescent tubes, flexos, CRTs and status LEDs.

  Each light is two circles over the same fixture: a tight core and a much
  wider wall wash. They run at different speeds, so they drift apart and never
  line up again — that is what stops the pulse reading as a loop. Positions
  come from the room data in source-image coordinates and are projected
  exactly like a hotspot, so a halo stays on its fitting at every viewport
  size.

  No mix-blend-mode here, on purpose. A blended element only has something to
  blend with while it sits inside the same isolated group as the wallpaper,
  and satisfying that would force this layer underneath the room tint instead
  of over it. Warm colour over graphite paint does the same job unblended.
*/
.room-lights {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  transition: opacity 200ms ease-out;
  pointer-events: none;
}

.room-lights.is-lit {
  opacity: 1;
}

.room-light {
  position: absolute;
  border-radius: 50%;
  /*
    The box arrives square and gets squashed into the painted shape here, so
    everything inside it can stay a plain circle. A ceiling panel is wide and
    low, a strip light is long and thin, a bulb is round: same element, three
    scales.
  */
  transform: scale(var(--squash-x, 1), var(--squash-y, 1));
}

.room-light::before,
.room-light::after {
  content: "";
  position: absolute;
  border-radius: 50%;
}

/*
  Fluorescent tubes, flexos, the lamp over a lift door.

  A tube does not gutter like a flame; it sits at level and its ballast lets
  it sag a little, and every so often it dips harder and recovers. So these
  curves hold near the top and drop briefly, twice per cycle, at uneven
  intervals — an even swing would read as an indicator blinking rather than as
  a fitting that has been on for thirty years.
*/
.room-light--lamp::before {
  inset: 0;
  background:
    radial-gradient(
      circle,
      rgba(227,216,191,.46),
      rgba(201,122,61,.2) 44%,
      transparent 70%
    );
  will-change: opacity, transform;
  animation: lamp-core 7.3s var(--phase, 0s) ease-in-out infinite;
}

/*
  The wash reaches well past the core — inset is negative so it spills onto
  the surrounding wall — and stays faint. It carries most of the sense of a
  living fitting; the core alone just looks like a lamp being dimmed. The two
  cycle lengths share no useful factor, so core and wash drift apart and only
  line up again minutes later.
*/
.room-light--lamp::after {
  inset: -55%;
  background: radial-gradient(circle, rgba(201,122,61,.15), transparent 66%);
  opacity: .8;
  animation: lamp-wash 10.4s var(--phase, 0s) ease-in-out infinite;
}

@keyframes lamp-core {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  13% {
    opacity: .96;
    transform: scale(1.01);
  }
  21% {
    opacity: .78;
    transform: scale(.96);
  }
  29% {
    opacity: .97;
    transform: scale(1.01);
  }
  46% {
    opacity: 1;
    transform: scale(1.03);
  }
  55% {
    opacity: .85;
    transform: scale(.98);
  }
  63% {
    opacity: .98;
    transform: scale(1.01);
  }
  81% {
    opacity: 1;
    transform: scale(1.02);
  }
  89% {
    opacity: .91;
    transform: scale(.99);
  }
}

@keyframes lamp-wash {
  0%, 100% {
    opacity: .84;
    transform: scale(1);
  }
  17% {
    opacity: .92;
    transform: scale(1.03);
  }
  31% {
    opacity: .66;
    transform: scale(.96);
  }
  46% {
    opacity: .88;
    transform: scale(1.02);
  }
  67% {
    opacity: .72;
    transform: scale(.98);
  }
  84% {
    opacity: .9;
    transform: scale(1.04);
  }
}

/*
  Phosphor.

  A monochrome tube throws far less light than it looks like it does, so the
  core is tight and the bloom around it is barely there. What sells it is that
  it never sits still: the beam current wanders with whatever the machine is
  drawing, which is a slow drift rather than a flicker.
*/
.room-light--crt::before {
  inset: 12%;
  background:
    radial-gradient(
      circle,
      rgba(127,174,155,.4),
      rgba(127,174,155,.16) 48%,
      transparent 72%
    );
  will-change: opacity, transform;
  animation: crt-glow 8.1s var(--phase, 0s) ease-in-out infinite;
}

.room-light--crt::after {
  inset: -40%;
  background: radial-gradient(circle, rgba(127,174,155,.1), transparent 62%);
  opacity: .7;
  animation: crt-glow 12.7s var(--phase, 0s) ease-in-out infinite reverse;
}

@keyframes crt-glow {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  23% {
    opacity: .82;
    transform: scale(.98);
  }
  41% {
    opacity: 1;
    transform: scale(1.03);
  }
  68% {
    opacity: .88;
    transform: scale(.99);
  }
  86% {
    opacity: .97;
    transform: scale(1.02);
  }
}

/*
  Indicators and lit signage.

  Small, saturated, and the only lights in the room allowed to pulse evenly:
  a status LED is machinery, and reading as machinery is the point. Kept dim
  enough that a row of them never competes with a lamp.
*/
.room-light--signal::before {
  inset: 24%;
  background: radial-gradient(circle, rgba(201,122,61,.5), transparent 66%);
  will-change: opacity;
  animation: signal-pulse 4.6s var(--phase, 0s) ease-in-out infinite;
}

.room-light--signal::after {
  inset: -30%;
  background: radial-gradient(circle, rgba(201,122,61,.12), transparent 60%);
}

@keyframes signal-pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: .55;
  }
}

/*
  Reduced motion keeps every fitting lit and stops the movement. The rooms are
  painted dark and rely on these halos to read as lit at all.
*/
@media (prefers-reduced-motion: reduce) {
  .room-light::before,
  .room-light::after {
    animation: none;
  }
}

/*
  Dust in the air.

  Two layers of sparse specks drifting in different directions at different
  speeds, which is enough to suggest depth without anything resembling a
  particle system. Each layer travels exactly one tile per cycle, so the loop
  has no seam, and each carries two offset copies of the same grid so the
  spacing does not read as a grid.
*/
.room-dust {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.room-dust::before,
.room-dust::after {
  content: "";
  position: absolute;
  /* Oversized so a full tile of drift never pulls an edge into view. */
  inset: -30%;
  will-change: transform;
}

.room-dust::before {
  background-image:
    radial-gradient(circle, rgba(227,216,191,.58) 0 1.1px, transparent 1.9px),
    radial-gradient(circle, rgba(227,216,191,.38) 0 .9px, transparent 1.6px);
  background-size: 190px 190px;
  background-position: 0 0, 83px 121px;
  animation: dust-near 54s linear infinite;
}

.room-dust::after {
  background-image:
    radial-gradient(circle, rgba(227,216,191,.34) 0 .9px, transparent 1.6px),
    radial-gradient(circle, rgba(127,174,155,.22) 0 .8px, transparent 1.4px);
  background-size: 269px 269px;
  background-position: 0 0, 137px 61px;
  animation: dust-far 83s linear infinite;
}

@keyframes dust-near {
  to {
    transform: translate3d(-190px, -190px, 0);
  }
}

@keyframes dust-far {
  to {
    transform: translate3d(269px, -269px, 0);
  }
}

/*
  Dust is nothing but motion. A frozen field of specks reads as dirt on the
  screen, so under reduced motion it goes away entirely rather than stopping.
*/
@media (prefers-reduced-motion: reduce) {
  .room-dust {
    display: none;
  }
}

.room-hotspots {
  z-index: 2;
  pointer-events: none;
}

.room-hotspot {
  position: absolute;
  pointer-events: auto;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--warm-fluorescent);
  cursor: pointer;
}

.room-hotspot::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px dashed transparent;
  background: radial-gradient(ellipse at center, rgba(201,122,61,.16), transparent 68%);
  opacity: 0;
  transition: opacity 140ms ease-out;
}

.room-hotspot::after {
  content: attr(data-hint);
  position: absolute;
  left: 14px;
  bottom: 14px;
  padding: 4px 7px;
  border: 1px solid var(--edge);
  background: rgba(27,29,32,.92);
  box-shadow: 0 2px 8px var(--shadow);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity 140ms ease-out, transform 140ms ease-out;
}

.room-hotspot:hover::before,
.room-hotspot:focus-visible::before {
  border-color: rgba(201,122,61,.55);
  opacity: 1;
}

.room-hotspot:hover::after,
.room-hotspot:focus-visible::after {
  opacity: 1;
  transform: translateY(0);
}

.room-hotspot:focus-visible {
  outline: 2px solid var(--warm-fluorescent);
  outline-offset: -6px;
}

.room-hotspot:disabled {
  cursor: wait;
}

/*
  SIGNAL / 03 shares the right-hand rail with the feed monitor and obeys the
  same rule at full size: software over the room, below any window, so content
  wins when the two planes meet.

  The compact form is the one documented exception. Between 761px and 1280px
  SIGNAL / 02 is hidden because a 940px window and a useful monitor cannot
  coexist, but a radio stays useful with no screen space at all — so it drops
  to a 28px transport strip and rises above the window layer, because a
  transport nobody can reach is worse than a transport nobody can see.
*/
.signal-radio {
  position: absolute;
  top: 20px;
  right: 24px;
  z-index: 3;
  width: 280px;
  overflow: hidden;
  border: 1px solid var(--edge);
  background: rgba(37, 40, 45, .78);
  color: var(--ink-soft);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark),
    0 4px 16px var(--shadow);
  pointer-events: auto;
}

.signal-radio__header {
  padding: 8px 11px 7px;
  border-bottom: var(--divider-subtle);
  background: rgba(37, 40, 45, .89);
}

.signal-radio__module,
.signal-radio__status,
.signal-radio__line,
.signal-radio__selection,
.signal-radio__detent,
.signal-radio__toggle {
  font-family: var(--font-terminal);
  letter-spacing: .07em;
  text-transform: uppercase;
}

.signal-radio__module {
  display: block;
  margin-bottom: 4px;
  color: var(--ink-dim);
  font-size: 9px;
}

.signal-radio__identity {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.signal-radio__identity h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-brand);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: var(--tracking-title);
}

.signal-radio__status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--phosphor);
  font-size: 8px;
}

.signal-radio__status::before {
  content: "";
  width: 5px;
  height: 5px;
  background: currentColor;
}

.signal-radio[data-radio-state="off"] .signal-radio__status {
  color: var(--ink-dim);
}

.signal-radio[data-radio-state="tuning"] .signal-radio__status {
  color: var(--accent);
}

.signal-radio[data-radio-state="error"] .signal-radio__status {
  color: var(--alert-lit);
}

.signal-radio__stage {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  align-items: center;
  gap: 11px;
  padding: 11px;
  background: rgba(22, 27, 25, .28);
}

/*
  The reserved circular analyzer, finally driven by proportional data. Only
  its size is contextual here; the conic contract is the primitive's.
*/
.signal-radio .signal-radio__level {
  width: 44px;
}

.signal-radio .signal-radio__level::before {
  inset: 5px;
}

.signal-radio .signal-radio__level > span {
  font-size: 9px;
  font-variant-numeric: tabular-nums;
}

.signal-radio__ladder {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 2px;
  height: 48px;
}

.signal-radio__bar {
  position: relative;
  background-image: repeating-linear-gradient(0deg, var(--edge-soft) 0 2px, transparent 2px 4px);
}

/*
  The fill is clipped rather than scaled so the segment grid stays rigid, the
  way a real LED ladder lights up. A hot band drifts from phosphor to amber;
  browsers without color-mix keep the flat phosphor fill above.
*/
.signal-radio__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(0deg, var(--phosphor) 0 2px, transparent 2px 4px);
  background-image: repeating-linear-gradient(
    0deg,
    color-mix(in oklab, var(--phosphor), var(--accent-lit) calc(var(--band, 0) * 100%)) 0 2px,
    transparent 2px 4px
  );
  clip-path: inset(calc(100% - var(--band, 0) * 100%) 0 0 0);
}

.signal-radio__plate {
  margin: 0;
  padding: 8px 11px 9px;
  border-top: var(--divider-subtle);
}

.signal-radio__line {
  margin: 0;
  color: var(--ink-dim);
  font-size: 8px;
  line-height: 1.7;
  white-space: nowrap;
}

.signal-radio__line span {
  color: var(--edge-strong);
}

.signal-radio__credit {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--edge-soft);
}

.signal-radio__credit:hover,
.signal-radio__credit:focus-visible {
  outline: 0;
  color: var(--accent-lit);
  border-bottom-color: var(--accent);
}

.signal-radio__credit:focus-visible {
  box-shadow: 0 0 0 var(--focus-width) var(--focus-color);
}

.signal-radio__footer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  min-height: 76px;
  padding: 6px 10px;
  border-top: var(--divider-subtle);
  background: rgba(37, 40, 45, .89);
}

/*
  One mechanical control carries the radio's visual identity. The numbered
  marks are real detents, not decoration: the pointer stops on the station
  selected by the adjacent readout.
*/
.signal-radio__selector {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  align-items: center;
  min-width: 0;
}

.signal-radio__dial-bank {
  position: relative;
  grid-area: 1 / 1;
  width: 64px;
  height: 64px;
}

.signal-radio__detent {
  position: absolute;
  color: var(--edge-strong);
  font-size: 7px;
  line-height: 1;
}

.signal-radio__detent--one {
  top: 15px;
  left: 1px;
}

.signal-radio__detent--two {
  top: 0;
  left: 34%;
  transform: translateX(-50%);
}

.signal-radio__detent--three {
  top: 0;
  left: 66%;
  transform: translateX(-50%);
}

.signal-radio__detent--four {
  top: 15px;
  right: 1px;
}

.signal-radio__dial {
  --dial-angle: -54deg;
  position: relative;
  z-index: 1;
  grid-area: 1 / 1;
  place-self: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--edge-strong);
  border-radius: 50%;
  background: var(--surface-sunken);
  cursor: pointer;
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -2px -2px 0 var(--relief-dark),
    2px 3px 0 rgba(0, 0, 0, .28);
}

.signal-radio__dial::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid var(--edge-soft);
  border-radius: inherit;
  background:
    repeating-conic-gradient(from 4deg, var(--edge-soft) 0 2deg, transparent 2deg 14deg),
    var(--surface-raised);
}

.signal-radio__dial-face {
  position: absolute;
  inset: 8px;
  z-index: 1;
  display: block;
  border: 1px solid var(--edge);
  border-radius: inherit;
  background: var(--surface);
  transform: rotate(var(--dial-angle));
  transition: transform var(--motion-fast) var(--ease-mechanical);
}

.signal-radio__dial-pointer {
  position: absolute;
  top: 2px;
  left: 50%;
  width: 2px;
  height: 9px;
  background: var(--accent-lit);
  box-shadow: 1px 0 0 var(--edge);
  transform: translateX(-50%);
}

.signal-radio__dial-hub {
  position: absolute;
  inset: 7px;
  border: 1px solid var(--edge);
  border-radius: inherit;
  background: var(--surface-raised);
}

.signal-radio__dial:hover {
  border-color: var(--accent);
}

.signal-radio__dial:focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

.signal-radio__selection {
  min-width: 0;
  margin: 0;
  padding-left: 5px;
}

.signal-radio__selection span,
.signal-radio__selection a {
  display: block;
}

.signal-radio__selection span {
  margin-bottom: 3px;
  color: var(--accent-lit);
  font-size: 6px;
}

.signal-radio__selection a {
  overflow: hidden;
  color: var(--ink-soft);
  font-size: 7px;
  font-weight: 500;
  line-height: 1.25;
  text-decoration: none;
  text-overflow: ellipsis;
}

.signal-radio__selection a:hover,
.signal-radio__selection a:focus-visible {
  color: var(--accent-lit);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.signal-radio__selection a:focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

.signal-radio__toggle {
  min-width: 62px;
  min-height: 38px;
  padding: 5px 8px;
  border: 1px solid var(--edge);
  background: var(--surface-raised);
  color: var(--ink-soft);
  font-size: 9px;
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical);
}

.signal-radio__toggle:hover {
  border-color: var(--edge-strong);
  color: var(--ink);
}

.signal-radio__toggle:focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

.signal-radio[data-radio-state="on"] .signal-radio__toggle,
.signal-radio[data-radio-state="tuning"] .signal-radio__toggle {
  border-color: var(--accent);
  color: var(--accent-lit);
}

/*
  SIGNAL / 02 is software laid over the room, not another window and not part
  of the furniture in the painting. It stays below normal application windows
  so content always wins when the two planes meet.
*/
.signal-feed {
  --signal-item-height: 62px;
  position: absolute;
  right: 24px;
  bottom: 20px;
  z-index: 3;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) 24px;
  width: 280px;
  height: 332px;
  overflow: hidden;
  border: 1px solid var(--edge);
  background: rgba(37, 40, 45, .78);
  color: var(--ink-soft);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark),
    0 4px 16px var(--shadow);
  pointer-events: auto;
}

.signal-feed__header {
  padding: 8px 11px 7px;
  border-bottom: var(--divider-subtle);
  background: rgba(37, 40, 45, .89);
}

.signal-feed__module,
.signal-feed__status,
.signal-feed__source,
.signal-feed__age,
.signal-feed__footer {
  font-family: var(--font-terminal);
  letter-spacing: .07em;
  text-transform: uppercase;
}

.signal-feed__module {
  display: block;
  margin-bottom: 4px;
  color: var(--ink-dim);
  font-size: 9px;
}

.signal-feed__identity {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.signal-feed__identity h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-brand);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: var(--tracking-title);
}

.signal-feed__status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--terminal-green);
  font-size: 8px;
}

.signal-feed__status::before {
  content: "";
  width: 5px;
  height: 5px;
  background: currentColor;
}

.signal-feed[data-feed-state="loading"] .signal-feed__status {
  color: var(--ink-dim);
}

.signal-feed[data-feed-state="offline"] .signal-feed__status,
.signal-feed[data-feed-state="empty"] .signal-feed__status {
  color: var(--alert-lit);
}

.signal-feed__viewport {
  min-height: 0;
  overflow: hidden;
  background: rgba(22, 27, 25, .28);
  scrollbar-width: thin;
  scrollbar-color: var(--edge) var(--surface-sunken);
}

.signal-feed__list {
  margin: 0;
  padding: 0;
  list-style: none;
  transform: translateY(0);
  transition: transform 520ms var(--ease-mechanical);
  will-change: transform;
}

.signal-feed__list.is-rotating {
  transform: translateY(calc(-1 * var(--signal-item-height)));
}

.signal-feed__list.is-resetting {
  transform: translateY(0);
  transition: none;
}

.signal-feed__item {
  height: var(--signal-item-height);
  border-bottom: var(--divider-subtle);
}

.signal-feed__link {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: 13px minmax(0, 1fr);
  column-gap: 8px;
  height: 100%;
  padding: 7px 11px 6px;
  color: inherit;
  text-decoration: none;
  transition: background var(--motion-fast) var(--ease-mechanical);
}

.signal-feed__link::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 2px;
  background: transparent;
}

.signal-feed__source {
  min-width: 0;
  color: var(--ink-dim);
  font-size: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.signal-feed__title {
  grid-column: 1 / -1;
  display: -webkit-box;
  overflow: hidden;
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.25;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.signal-feed__age {
  color: var(--ink-dim);
  font-size: 8px;
  font-variant-numeric: tabular-nums;
  text-transform: none;
}

.signal-feed__link:hover,
.signal-feed__link:focus-visible {
  outline: 0;
  background: rgba(201, 122, 61, .07);
}

.signal-feed__link:hover::before,
.signal-feed__link:focus-visible::before {
  background: var(--accent);
}

.signal-feed__link:focus-visible {
  box-shadow: inset 0 0 0 var(--focus-width) var(--focus-color);
}

.signal-feed__empty {
  padding: 18px 12px;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 1.45;
}

.signal-feed__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 11px;
  border-top: var(--divider-subtle);
  background: rgba(37, 40, 45, .89);
  color: var(--ink-dim);
  font-size: 8px;
}

.signal-feed__footer [data-signal-feed-updated] {
  text-transform: none;
}

.window-layer {
  position: absolute;
  inset: 0;
  z-index: 10;
  pointer-events: none;
}

/* A quiet software plane over the physical room; no blur, no lost detail. */
.window-layer::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(12, 14, 15, .12);
  pointer-events: none;
}

.window {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  height: var(--h);
  max-width: calc(100vw - 220px);
  max-height: calc(100% - 32px);
  display: grid;
  grid-template-rows: 34px minmax(0, 1fr);
  overflow: hidden;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark),
    0 4px 16px var(--shadow);
  pointer-events: auto;
  transform-origin: 50% 35%;
  animation: window-in var(--motion-standard) var(--ease-mechanical) both;
  transition:
    border-color var(--motion-fast) var(--ease-mechanical),
    box-shadow var(--motion-standard) var(--ease-mechanical);
}

.window[hidden] {
  display: none;
}

.window.is-focused {
  border-color: var(--edge);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark),
    0 6px 22px var(--shadow);
}

.window.is-minimized {
  display: none;
}

.window__bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  border-bottom: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
  color: var(--ink-dim);
  user-select: none;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    border-color var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical);
}

@media (min-width: 761px) and (pointer: fine) {
  .window__bar {
    cursor: grab;
    touch-action: none;
  }

  .window.is-dragging .window__bar {
    cursor: grabbing;
  }
}

.window__title {
  display: grid;
  grid-template-columns: 2px auto minmax(0, 1fr);
  align-items: center;
  align-self: stretch;
  gap: 0;
  min-width: 0;
  padding-right: var(--space-5);
  font-family: var(--font-brand);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
}

.window__title > [id] {
  min-width: 0;
  padding-left: var(--space-5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.window__gem {
  flex: 0 0 auto;
  align-self: stretch;
  width: 2px;
  height: auto;
  border: 0;
  background: transparent;
  transform: none;
  transform-origin: 50% 50%;
}

/*
  Active window. Three quiet signals rather than one loud one: the spine
  lights amber, the bar comes forward one surface step, and the title goes
  from --ink-dim to full --ink. None of them recolours the frame.
*/
.window.is-focused .window__bar {
  border-bottom-color: var(--edge);
  background: var(--surface-raised);
  color: var(--ink);
}

.window.is-focused .window__gem {
  background: var(--accent);
}

/*
  Session activation is one compact event in the header, not a window-scale
  flourish. It only runs when focus moves between modules; clicking inside the
  already active window does not restart it.
*/
.window.is-activating .window__bar {
  animation: session-activate var(--motion-standard) var(--ease-mechanical);
}

.window.is-activating .window__gem {
  animation: session-spine var(--motion-standard) var(--ease-mechanical);
}

/*
  The small system code beside a title — ARCHIVO / 03. It is navigation
  furniture, not atmosphere, so it stays --ink-dim on the active window too
  and never competes with the name it follows.
*/
.window__module {
  flex: 0 0 auto;
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-5);
  border-right: var(--divider-subtle);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.window__state {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-right: var(--space-4);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 9px;
  letter-spacing: .08em;
}

.window__state::before {
  content: "";
  width: 5px;
  height: 5px;
  background: var(--edge-soft);
}

.window[data-state="active"] .window__state {
  color: var(--accent-lit);
}

.window[data-state="active"] .window__state::before {
  background: var(--accent);
}

.window[data-state="idle"] .window__state::before {
  background: var(--oxidized-olive);
}

.window__controls {
  display: flex;
  align-self: stretch;
}

.window__controls button {
  min-width: 54px;
  height: 100%;
  padding: 0 var(--space-4);
  border: 0;
  border-left: 1px solid var(--edge-soft);
  background: transparent;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 9px;
  font-weight: 400;
  letter-spacing: .06em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical),
    box-shadow var(--motion-fast) var(--ease-mechanical);
}

.window__controls button:hover {
  background: var(--surface-raised);
  color: var(--ink);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.window__body {
  position: relative;
  min-height: 0;
  overflow: hidden;
  background: var(--surface);
}

/* Optional status strip: opt in with .window__body--with-status. */
.window__body--with-status .window__content {
  bottom: 22px;
}

.window__statusbar {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  height: 22px;
  padding: 0 var(--space-4);
  border-top: var(--divider-subtle);
  background: var(--surface-sunken);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: var(--text-meta);
}

/*
  Only this viewport scrolls.

  It used to be inset by ~32px on every side to clear a drawn SVG frame that
  was painted over the body. The frame is gone — an operating system draws
  its borders in CSS — so the box fills the body and pays for its own margin
  in padding, which is what lets a pane like the reader or the manual run to
  the window's edge when it wants to.
*/
.window__content {
  position: absolute;
  inset: 0;
  z-index: 1;
  min-width: 0;
  min-height: 0;
  overflow: auto;
  padding: 20px 22px 24px;
  background: transparent;
  scrollbar-width: thin;
  scrollbar-color: var(--edge) var(--surface-sunken);
}

.window__content h1,
.window__content h2,
.window__content h3,
.window__content p {
  margin-top: 0;
}

/*
  The base link, for every anchor in a window that has not been given one.

  Thirteen links across the manual, the cards and the article footers were
  rendering at the browser default #0000EE — a blue belonging to no palette,
  old or new. It went unnoticed while the desktop was violet and gold; with
  everything else agreeing on seven colours it is the loudest thing on screen.

  Signal Amber is 3.94:1 on this surface, so a link cannot simply be amber —
  it was not readable on the light sheet either, at 2.3. It keeps the ink of
  the text around it and takes the accent on the underline, which is where
  docs/PALETTE.md puts the amber anyway: the border, the underline, the icon.

  Wrapped in :where() so it carries no specificity at all: every component
  that styles its own anchors (.entry__title, .manual__topic-link,
  .reader__back, .mail__direct a) still wins without out-specifying this.
*/
:where(.window__content) :where(a) {
  color: var(--ink);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

:where(.window__content) :where(a):hover {
  color: var(--accent-lit);
  text-decoration-color: var(--accent-lit);
}

.window__content h1 {
  max-width: 13ch;
  margin-bottom: 16px;
  font-family: var(--font-brand);
  font-size: clamp(35px, 4vw, 55px);
  font-weight: 700;
  line-height: 1.01;
  letter-spacing: -.005em;
  color: var(--ink);
}

.window__content h2 {
  max-width: 18ch;
  margin-bottom: 16px;
  font-family: var(--font-brand);
  font-size: clamp(28px, 3vw, 42px);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -.005em;
  color: var(--ink);
}

.window__content h3 {
  margin-bottom: 7px;
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}

.window__content p {
  max-width: 72ch;
  color: var(--ink-soft);
}

.welcome {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(240px, 34%, 340px);
  gap: clamp(18px, 3vw, 42px);
  align-items: end;
}

.welcome__copy {
  min-width: 0;
  align-self: start;
}

.welcome__mark {
  align-self: center;
  justify-self: center;
  width: min(100%, 300px);
  aspect-ratio: 1;
  background: var(--signal-amber);
  opacity: 1;
  -webkit-mask: url("./assets/mascot/pug-emblem.png") center / contain no-repeat;
  mask: url("./assets/mascot/pug-emblem.png") center / contain no-repeat;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .14em;
}

.eyebrow::before {
  content: "";
  flex: 0 0 auto;
  width: 10px;
  height: 2px;
  background: var(--accent);
}

.lead {
  max-width: 54ch;
  color: var(--ink-soft);
  font-size: clamp(16px, 1.4vw, 19px);
}

/* Un rotulo que abre una seccion nueva necesita aire por arriba; pegado a la
   rejilla o a la lista anterior se lee como parte de ella. */
.brief-list + .eyebrow,
.record-list + .eyebrow,
.detail-list + .eyebrow,
.diagram-module + .eyebrow,
.file-list + .eyebrow,
.principles + .eyebrow {
  margin-top: 26px;
}

.welcome__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 12px 0 20px;
}

.button {
  min-height: 32px;
  padding: 7px 15px;
  border: 1px solid var(--edge);
  border-radius: 0;
  background: var(--surface-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark);
  transition: background 130ms ease-out, border-color 130ms ease-out, color 130ms ease-out;
}

.button:hover {
  border-color: var(--edge-strong);
  background: #454A51;
  color: var(--accent-lit);
}

.button:active {
  box-shadow:
    inset 1px 1px 0 var(--relief-dark),
    inset -1px -1px 0 var(--relief-light);
}

.button--primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--screen);
}

/*
  A standalone CTA continues the document's reading flow, so it stays aligned
  to the left rather than borrowing the right-aligned language of dialog
  confirmation buttons. The explicit top margin keeps it from fusing to the
  bordered module immediately before it; base content paragraphs intentionally
  have no top margin, so the action row has to own this spacing itself.
*/
.window__content p:has(> .button:only-child) {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: flex-start;
  margin: var(--space-6) 0 0;
}

.quiet,
.form-note,
.file-row small {
  color: var(--ink-dim) !important;
  font-size: 13px;
  font-family: var(--font-ui);
}

/*
  Phase 4 primitive permissions:
  - BriefModule: measured segment rails and evidence-availability matrices.
  - Record collections: one coordinate divider at the collection boundary.
  - DetailStrip: evidence-availability matrix only.
  - DiagramModule: node graphs and their signal-trace connectors.
  - ConsoleModule: signal traces only when driven by live state.
  - CircularAnalyzer: reserved for honest proportional data; no current use.
*/
.coordinate-divider {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) 24px;
  gap: var(--space-3);
  align-items: end;
  margin-top: var(--space-6);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 9px;
  letter-spacing: .06em;
}

.coordinate-divider > span:last-child {
  text-align: right;
}

.coordinate-divider__scale {
  height: 7px;
  border-bottom: var(--divider-strong);
  background: repeating-linear-gradient(
    to right,
    var(--edge-soft) 0 var(--stroke-hairline),
    transparent var(--stroke-hairline) 10px
  );
}

.dot-matrix {
  display: inline-block;
  flex: 0 0 auto;
  width: 3px;
  height: 3px;
  margin: 0 6px 5px 1px;
  background: currentColor;
  color: var(--edge-soft);
  box-shadow: 5px 0 currentColor, 0 5px currentColor, 5px 5px currentColor;
}

.dot-matrix--available {
  color: var(--terminal-green);
}

.segment-rail {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-5);
}

.segment-rail__track {
  position: relative;
  display: block;
  height: 5px;
  background: repeating-linear-gradient(
    to right,
    var(--edge-soft) 0 calc(100% / 12 - 2px),
    transparent calc(100% / 12 - 2px) calc(100% / 12)
  );
}

.segment-rail__track::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--rail-start) * 100% / 12);
  width: calc(var(--rail-span) * 100% / 12);
  background: repeating-linear-gradient(
    to right,
    var(--accent) 0 calc(100% / var(--rail-span) - 2px),
    transparent calc(100% / var(--rail-span) - 2px) calc(100% / var(--rail-span))
  );
}

.segment-rail__legend {
  display: flex;
  justify-content: space-between;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 8px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.segment-rail__legend::before {
  content: "01";
}

.segment-rail__legend::after {
  content: "12";
}

.signal-trace {
  display: block;
  width: 100%;
  height: 18px;
  overflow: visible;
}

.signal-trace path {
  fill: none;
  stroke: var(--terminal-green);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

.node-graph {
  display: grid;
  grid-template-columns: auto minmax(32px, 1fr) auto minmax(32px, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: var(--space-4);
  border-bottom: var(--divider-strong);
  background: var(--surface-sunken);
}

.node-graph__node {
  padding: var(--space-3) var(--space-4);
  border: var(--divider-subtle);
  color: var(--ink-soft);
  font-family: var(--font-terminal);
  font-size: 9px;
  letter-spacing: .05em;
  text-align: center;
  text-transform: uppercase;
}

.node-graph__node--output {
  border-color: var(--accent);
  color: var(--accent-lit);
}

.node-graph + .record-list {
  margin-top: var(--space-4);
}

.circular-analyzer {
  position: relative;
  display: grid;
  place-items: center;
  width: 72px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(
    var(--terminal-green) 0 calc(var(--analyzer-value) * 1%),
    var(--edge-soft) calc(var(--analyzer-value) * 1%) 100%
  );
}

.circular-analyzer::before {
  content: "";
  position: absolute;
  inset: 7px;
  border-radius: inherit;
  background: var(--surface-sunken);
}

.circular-analyzer > span {
  position: relative;
  color: var(--ink-soft);
  font-family: var(--font-terminal);
  font-size: 10px;
}

.brief-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: var(--space-6);
  border-top: var(--divider-strong);
}

@media (min-width: 761px) {
  .brief-list--metrics {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .brief-list--metrics .brief-module {
    border-right: var(--divider-subtle);
  }

  .brief-list--metrics .brief-module:last-child {
    border-right: 0;
  }
}

.brief-module {
  position: relative;
  min-width: 0;
  padding: var(--space-6) var(--space-6) var(--space-6) 58px;
  border-bottom: var(--divider-subtle);
  background: transparent;
}

.brief-module:nth-child(odd) {
  border-right: var(--divider-subtle);
}

.brief-module::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 42px;
  border-left: var(--divider-subtle);
}

.brief-module::after {
  content: "";
  position: absolute;
  top: var(--space-6);
  left: 42px;
  width: var(--stroke-active);
  height: 18px;
  background: var(--accent);
}

.brief-module__header {
  min-width: 0;
}

.brief-module__header h3 {
  margin-bottom: var(--space-4);
}

.brief-module__index {
  position: absolute;
  top: 18px;
  left: var(--space-4);
  width: 26px;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tracking-meta);
  text-align: center;
}

.brief-module p {
  margin-bottom: var(--space-4);
  font-size: 13px;
}

.brief-module p.brief-module__symptom {
  margin-bottom: var(--space-4);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}

.brief-module__label {
  display: block;
  margin: calc(var(--space-2) * -1) 0 var(--space-4);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}

.brief-module__meta {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-5) 0 0;
  padding-top: var(--space-4);
  border-top: var(--divider-subtle);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
}

.brief-module__meta div {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: var(--space-4);
}

.brief-module__meta dt,
.brief-module__meta dd {
  margin: 0;
}

.brief-module__meta dd {
  min-width: 0;
}

.brief-module__meta dd:has(.dot-matrix) {
  display: inline-flex;
  align-items: center;
}

.brief-module__meta dt {
  color: var(--terminal-green);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.brief-module--compact {
  padding-bottom: var(--space-5);
}

.brief-module--compact p:last-child {
  margin-bottom: 0;
}

.record-list {
  display: grid;
  gap: 0;
  margin: var(--space-6) 0 0;
  padding: 0;
  border-top: var(--divider-strong);
  list-style: none;
}

.record-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: var(--space-5);
  padding: var(--space-5) 0;
  border-bottom: var(--divider-subtle);
}

.record-row__index {
  padding-top: var(--space-1);
  border-right: var(--stroke-active) solid transparent;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
  letter-spacing: var(--tracking-meta);
  transition: border-color var(--motion-fast) var(--ease-mechanical);
}

.record-row:hover .record-row__index {
  border-right-color: var(--accent);
}

.record-row strong {
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 16px;
}

.record-row p {
  margin: var(--space-2) 0 0;
  font-size: 14px;
}

.principles {
  display: grid;
  gap: 0;
  margin: 18px 0 0;
  padding: 0;
  border-top: 1px solid var(--edge-soft);
  list-style: none;
}

.principles li {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 12px;
  padding: 15px 0;
  border-bottom: 1px solid var(--edge-soft);
}

.principles li > span {
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .08em;
}

.principles strong {
  font-family: var(--font-ui);
  font-size: 16px;
  color: var(--ink);
}

.principles p {
  margin: 4px 0 0;
  font-size: 14px;
}

.detail-list {
  margin-top: var(--space-6);
  border-top: var(--divider-strong);
}

.detail-strip {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  gap: var(--space-5);
  align-items: center;
  padding: var(--space-5) var(--space-4);
  border-bottom: var(--divider-subtle);
  text-decoration: none;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical);
}

.detail-strip:hover {
  background: var(--surface-sunken);
}

.detail-strip__ref,
.detail-strip__action {
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.detail-strip__action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}

.detail-strip__action .dot-matrix {
  margin-bottom: 5px;
}

.detail-strip__body {
  min-width: 0;
}

.detail-strip__body strong,
.detail-strip__body small {
  display: block;
}

.detail-strip__body strong {
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
}

.detail-strip__body small {
  margin-top: var(--space-1);
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 12px;
}

.detail-strip:hover .detail-strip__action {
  color: var(--accent-lit);
}

.diagram-module {
  margin-top: var(--space-7);
  border-top: var(--divider-strong);
  border-bottom: var(--divider-strong);
  background: var(--surface-sunken);
}

.diagram-module__header {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  align-items: center;
  min-height: 34px;
  border-bottom: var(--divider-subtle);
}

.diagram-module__header > span {
  padding-left: var(--space-4);
  color: var(--terminal-green);
  font-family: var(--font-terminal);
  font-size: 10px;
  letter-spacing: .06em;
}

.diagram-module__header h3 {
  margin: 0;
  font-family: var(--font-brand);
  font-size: 13px;
  letter-spacing: var(--tracking-title);
  text-transform: uppercase;
}

.diagram-module__flow {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.diagram-module__flow li {
  position: relative;
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: var(--space-4);
  min-width: 0;
  padding: var(--space-5);
  border-bottom: var(--divider-subtle);
}

.diagram-module__flow li:nth-child(odd) {
  border-right: var(--divider-subtle);
}

.diagram-module__flow li:nth-last-child(-n + 2) {
  border-bottom: 0;
}

.diagram-module__node {
  position: relative;
  display: grid;
  place-items: center;
  align-self: start;
  width: 28px;
  height: 28px;
  border: var(--divider-strong);
  color: var(--accent-lit);
  font-family: var(--font-terminal);
  font-size: 10px;
}

.diagram-module__node::after {
  content: "";
  position: absolute;
  right: -9px;
  width: 8px;
  border-top: var(--divider-subtle);
}

.diagram-module__flow strong {
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
}

.diagram-module__flow p {
  margin: var(--space-2) 0 0;
  font-size: 13px;
}

.file-list {
  margin-top: 18px;
  border: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
}

.file-row {
  display: grid;
  grid-template-columns: 22px minmax(0,1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 11px 12px;
  border-bottom: 1px solid var(--edge-soft);
}

.file-row:last-child {
  border-bottom: 0;
}

.file-row strong,
.file-row small {
  display: block;
}

.file-row strong {
  font-family: var(--font-ui);
  color: var(--ink);
}

.file-row__icon {
  color: var(--accent);
  font-size: 14px;
}

.file-row__meta {
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
  letter-spacing: .04em;
}

/*
  Published work needs visible evidence, not another claim. This is a compact
  image viewer inside the Auspex case: the large readout carries the detail,
  while the filmstrip keeps all three screens visible and directly reachable.
  It uses the system's amber selection language; the product's own colours stay
  inside the captures rather than leaking into the surrounding OS chrome.
*/
.evidence-gallery {
  margin: var(--space-7) 0;
  border: 1px solid var(--edge);
  background: var(--surface-sunken);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark);
}

.evidence-gallery__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding: 9px 11px;
  border-bottom: var(--divider-strong);
  background: var(--surface-raised);
}

.evidence-gallery__header > div {
  min-width: 0;
}

.evidence-gallery__module,
.evidence-gallery__count {
  display: block;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 9px;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}

.evidence-gallery__module {
  margin-bottom: 3px;
}

.window__content .evidence-gallery__header h3 {
  margin: 0;
  overflow: hidden;
  color: var(--ink);
  font-family: var(--font-brand);
  font-size: 14px;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-title);
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.evidence-gallery__count {
  flex: 0 0 auto;
  color: var(--accent-lit);
  font-variant-numeric: tabular-nums;
}

.evidence-gallery__figure {
  margin: 0;
}

.evidence-gallery__stage {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) 36px;
  align-items: stretch;
  min-width: 0;
  border-bottom: var(--divider-subtle);
  background: var(--console);
}

.evidence-gallery__full-size {
  position: relative;
  display: grid;
  min-width: 0;
  place-items: center;
  background: #0D0F10;
  line-height: 0;
  text-decoration: none;
}

.evidence-gallery__full-size::after {
  content: "abrir ↗";
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 4px 6px;
  border: 1px solid var(--edge);
  background: rgba(27, 29, 32, .9);
  color: var(--ink-soft);
  font-family: var(--font-terminal);
  font-size: 9px;
  line-height: 1.2;
  letter-spacing: .05em;
  opacity: 0;
  text-transform: uppercase;
  transition: opacity var(--motion-fast) var(--ease-mechanical);
}

.evidence-gallery__full-size:hover::after,
.evidence-gallery__full-size:focus-visible::after {
  opacity: 1;
}

.evidence-gallery__full-size img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: contain;
}

.evidence-gallery__step {
  min-width: 0;
  padding: 0;
  border: 0;
  background: var(--surface-sunken);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical);
}

.evidence-gallery__step--previous {
  border-right: var(--divider-subtle);
}

.evidence-gallery__step--next {
  border-left: var(--divider-subtle);
}

.evidence-gallery__step:hover {
  background: var(--surface-raised);
  color: var(--accent-lit);
}

.evidence-gallery__step:active {
  background: var(--surface);
}

.evidence-gallery__caption {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-5);
  align-items: center;
  min-height: 48px;
  padding: 8px 11px;
  border-bottom: var(--divider-subtle);
  background: var(--surface);
}

.evidence-gallery__caption strong,
.evidence-gallery__caption small {
  display: block;
}

.evidence-gallery__caption strong {
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
}

.evidence-gallery__caption small {
  margin-top: 2px;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  line-height: 1.35;
}

.evidence-gallery__caption > a {
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 9px;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.evidence-gallery__strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.evidence-gallery__choice {
  position: relative;
  display: grid;
  min-width: 0;
  padding: 7px;
  border-right: var(--divider-subtle);
  background: var(--surface-sunken);
  color: var(--ink-dim);
  text-decoration: none;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical);
}

.evidence-gallery__choice:last-child {
  border-right: 0;
}

.evidence-gallery__choice::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 2px;
  background: transparent;
}

.evidence-gallery__choice:hover {
  background: var(--surface);
  color: var(--ink-soft);
}

.evidence-gallery__choice[aria-current="true"] {
  background: var(--surface-raised);
  color: var(--ink);
}

.evidence-gallery__choice[aria-current="true"]::before {
  background: var(--accent);
}

.evidence-gallery__choice img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--edge-soft);
  object-fit: cover;
}

.evidence-gallery__choice span {
  display: block;
  min-width: 0;
  margin-top: 6px;
  overflow: hidden;
  font-family: var(--font-ui);
  font-size: 11px;
  line-height: var(--leading-ui);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.evidence-gallery__choice b {
  margin-right: 5px;
  color: var(--accent-lit);
  font-family: var(--font-terminal);
  font-size: 9px;
  font-weight: 500;
}

@media (max-width: 520px) {
  .evidence-gallery__stage {
    grid-template-columns: 32px minmax(0, 1fr) 32px;
  }

  .evidence-gallery__caption {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2);
  }

  .evidence-gallery__caption > a {
    justify-self: start;
  }

  .evidence-gallery__choice {
    padding: 4px;
  }

  .evidence-gallery__choice span {
    font-size: 9px;
  }

  .evidence-gallery__choice b {
    display: block;
    margin: 0 0 2px;
  }
}

.contact-form {
  display: grid;
  gap: 14px;
  margin-top: 18px;
}

.contact-form label {
  display: grid;
  gap: 6px;
}

.contact-form label > span {
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .12em;
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  border: 1px solid var(--edge-soft);
  border-radius: 0;
  background: var(--surface-sunken);
  color: var(--ink);
  padding: 9px 10px;
  resize: vertical;
  font-family: var(--font-content);
  box-shadow: inset 1px 1px 0 var(--relief-dark);
}

.contact-form textarea {
  min-height: 112px;
  max-height: 200px;
}

.contact-form .button {
  justify-self: start;
}

.contact-form__trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-form[aria-busy="true"] .button {
  cursor: wait;
}

.form-note {
  margin: -2px 0 0;
}

.dock__home {
  flex: 0 0 auto;
  justify-content: center;
  width: 34px;
  padding: 0;
  border-right: 1px solid var(--edge-soft);
  color: var(--ink);
}

.dock__home.is-active::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-left: 5px;
  background: var(--accent);
}

.dock__tasks {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  overflow: hidden;
}

.dock__task {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  column-gap: var(--space-3);
  row-gap: 0;
  max-width: 250px;
  min-height: 32px;
  padding: 0 var(--space-4);
  color: var(--ink-dim);
  border-color: var(--edge-soft);
  background: transparent;
  font-family: var(--font-terminal);
  white-space: nowrap;
  overflow: hidden;
  transition:
    background var(--motion-fast) var(--ease-mechanical),
    border-color var(--motion-fast) var(--ease-mechanical),
    color var(--motion-fast) var(--ease-mechanical);
}

.dock__task-code {
  grid-column: 1;
  grid-row: 1;
  color: var(--ink-dim);
  font-size: 9px;
  letter-spacing: .06em;
}

.dock__task-label {
  grid-column: 1 / -1;
  grid-row: 2;
  min-width: 0;
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dock__task-state {
  grid-column: 2;
  grid-row: 1;
  color: var(--ink-dim);
  font-size: 8px;
  letter-spacing: .06em;
}

.dock__task.is-focused {
  color: var(--ink);
  border-color: var(--accent);
  background: transparent;
  box-shadow: inset 2px 0 0 var(--accent);
}

.dock__task.is-focused .dock__task-state {
  color: var(--accent-lit);
}

.dock__task:hover,
.dock__task:focus-visible {
  border-color: var(--edge-strong);
  background: var(--surface-sunken);
  color: var(--ink);
}

.dock__task:hover .dock__task-label,
.dock__task:focus-visible .dock__task-label {
  color: var(--ink);
}

.brand-chip:active,
.dock__home:active,
.dock__task:active,
.window__controls button:active {
  transform: translateY(1px);
}

.dock__task.is-minimized {
  background: transparent;
}

.dock__task.is-minimized .dock__task-label {
  color: var(--ink-dim);
}

.dock__hint {
  margin-left: auto;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
  letter-spacing: .06em;
  white-space: nowrap;
}

/*
  Start menu.

  The app icons are saturated illustrations on transparent backgrounds.
  Framing each one would have meant eight small boxes inside a box, so the
  panel takes the standard window surface and lets the illustrations supply
  the only colour in it. Hover marks the row the way every other list in this
  UI marks one: the surface lifts a step and an amber bar appears on the left.
*/
.dock__start {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}

.start-menu {
  position: absolute;
  left: 0;
  /* Clears the dock and stops just above its top border. */
  bottom: calc(100% + 8px);
  z-index: 1;
  display: grid;
  gap: 1px;
  width: 262px;
  max-width: calc(100vw - 24px);
  padding: 6px;
  border: 1px solid var(--edge);
  background: var(--surface);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    0 6px 20px var(--shadow);
}

.start-menu[hidden] {
  display: none;
}

.start-menu__item {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 7px 11px 7px 7px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background 120ms ease-out, color 120ms ease-out;
}

.start-menu__item::after {
  content: attr(data-module);
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 9px;
  letter-spacing: .06em;
}

.start-menu__item:hover,
.start-menu__item:focus-visible {
  border-left-color: var(--accent);
  background: var(--surface-raised);
  color: var(--ink);
}

.start-menu__glyph {
  display: block;
  width: 40px;
  height: 40px;
  object-fit: contain;
}

/*
  The apps open windows; the link leaves the site. The rule marks that break so
  the last entry does not read as a fifth app.
*/
.start-menu__separator {
  height: 0;
  margin: 5px 6px;
  border: 0;
  border-top: 1px solid var(--edge-soft);
}

.start-menu__item--link {
  text-decoration: none;
}

@keyframes window-in {
  from {
    opacity: 0;
    transform: translateY(6px) scale(.992);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes session-activate {
  from { background: var(--surface-sunken); }
  to { background: var(--surface-raised); }
}

@keyframes session-spine {
  from {
    opacity: .35;
    transform: scaleY(.35);
  }
  to {
    opacity: 1;
    transform: scaleY(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .signal-feed__list {
    transform: none !important;
    transition: none !important;
    will-change: auto;
  }

  .signal-feed__viewport {
    overflow-y: auto;
  }
}

/* Narrow-screen fallback: one window at a time, filling the desktop. */
@media (max-width: 760px) {
  :root {
    --topbar-h: 38px;
    --dock-h: 52px;
  }

  .status-pill,
  .dock__hint,
  .signal-feed,
  .signal-radio {
    display: none;
  }

  .window {
    left: 8px !important;
    top: 8px !important;
    width: calc(100vw - 16px) !important;
    height: calc(100% - 16px) !important;
    max-width: none;
    max-height: none;
  }

  .window__content {
    padding: 14px 14px 18px;
  }

  .brief-list,
  .brief-list--metrics,
  .diagram-module__flow {
    grid-template-columns: 1fr;
  }

  .brief-module,
  .brief-module:nth-child(odd),
  .brief-list--metrics .brief-module {
    border-right: 0;
  }

  .diagram-module__flow li:nth-child(odd),
  .diagram-module__flow li:nth-last-child(-n + 2) {
    border-right: 0;
    border-bottom: var(--divider-subtle);
  }

  .diagram-module__flow li:last-child {
    border-bottom: 0;
  }

  .detail-strip {
    grid-template-columns: 46px minmax(0, 1fr);
  }

  .detail-strip__action {
    display: none;
  }

  .dock__tasks {
    overflow-x: auto;
  }
}

/*
  Browser zoom reduces the available CSS viewport before the phone layout is
  reached. Keep the authored window size, but clamp its starting position so
  the controls remain reachable at the 960px-wide equivalent of 150% zoom on
  a 1440px display.
*/
@media (min-width: 761px) and (max-width: 1100px) {
  .window {
    left: max(8px, min(var(--x), calc(100vw - var(--w) - 8px)));
  }
}

/* Reserve the right workstation bay while both surfaces fit side by side. */
@media (min-width: 1281px) {
  .window--welcome {
    left: max(16px, min(var(--x), calc(100vw - var(--w) - 328px)));
  }
}

/* Below this point a 940px welcome window and a useful monitor cannot coexist. */
@media (min-width: 761px) and (max-width: 1280px) {
  .signal-feed {
    display: none;
  }

  /*
    The radio survives that cut as a transport strip: twelve bands, a lamp and
    the switch. It moves above the window layer here and only here, because at
    this width the rail it normally occupies is underneath an open window.
  */
  .signal-radio {
    top: auto;
    right: 12px;
    bottom: 12px;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 10px;
    width: auto;
    height: 28px;
    padding: 0 8px 0 10px;
  }

  .signal-radio__module,
  .signal-radio__identity h2,
  .signal-radio__level,
  .signal-radio__plate {
    display: none;
  }

  .signal-radio__header,
  .signal-radio__stage,
  .signal-radio__footer {
    padding: 0;
    border: 0;
    background: none;
  }

  .signal-radio__stage {
    display: block;
  }

  .signal-radio__footer {
    display: block;
    min-height: 0;
  }

  .signal-radio__selector {
    display: none;
  }

  .signal-radio__ladder {
    width: 104px;
    height: 16px;
  }

  .signal-radio__toggle {
    min-width: 0;
    min-height: 0;
    padding: 3px 9px;
  }
}

@media (max-width: 420px) {
  .brand-chip span:last-child,
  .dock__home span:last-child {
    font-size: 17px;
  }

  .window__content h1 {
    font-size: 35px;
  }

  .window__content h2 {
    font-size: 29px;
  }
}
/*
  Case.

  The site's own voice is lowercase — the window is called "archivo", not
  "ARCHIVE" — and that is copy, so it stays. What goes uppercase is only the
  OS furniture around it: title bars, section labels, field legends, the
  small identifiers. Those are the operating system talking, not us.
*/
.brand-chip,
.dock__task,
.dock__hint,
.button {
  text-transform: none;
}

/*
  The zebra that tells one row from the next. It has to be a *lighter* film
  now: on a dark ground the old white-on-light wash inverted into a smear.
*/
.file-row:nth-child(even) {
  background: rgba(227, 216, 191, .028);
}

/* Minimise reads as system, close reads as destructive. */
.window__controls button:first-child:hover {
  background: var(--surface-raised);
  color: var(--phosphor);
}

.window__controls button:last-child:hover {
  background: var(--surface-raised);
  color: var(--alert-lit);
}

.dock__home {
  width: 34px;
  min-width: 34px;
  padding: 0;
}

.window__content h1 {
  margin-bottom: 18px;
}

.window__content h2 {
  margin-bottom: 18px;
}

@media (max-width: 420px) {
  .window__content {
    padding: 12px 12px 16px;
  }

  .window__module {
    padding: 0 var(--space-4);
    font-size: 9px;
  }

  .window__state {
    width: 13px;
    margin-right: var(--space-2);
    font-size: 0;
  }

  .window__controls button {
    min-width: 48px;
    padding: 0 var(--space-3);
    font-size: 8px;
  }
}


@media (max-width: 900px) {
  .window__content h1 {
    font-size: clamp(34px, 5vw, 50px);
  }

  .window__content h2 {
    font-size: clamp(27px, 4vw, 39px);
  }
}

/* --- B6 targeted layout fixes ------------------------------------------ */

/*
  Inicio needs to fit as a compact welcome panel rather than vertically
  centering an oversized hero inside a scroll viewport.
*/
.window--welcome .window__content {
  padding: 26px 28px 28px;
}

.window--welcome .window__content h1 {
  max-width: 11ch;
  font-size: clamp(44px, 4.5vw, 62px);
  line-height: 1.02;
  margin-bottom: 16px;
}

.window--welcome .lead {
  font-size: clamp(15px, 1.25vw, 18px);
  margin-bottom: 14px;
}

.window--welcome .welcome__actions {
  margin: 8px 0 14px;
}

.window--welcome .quiet {
  margin-bottom: 0;
}

/* Keep the sub-pixel border crisp without adding another outline. */
.window {
  outline: 0;
}

@media (max-width: 760px) {
  .window--welcome .window__content {
    padding: 18px 16px 20px;
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .window--welcome .window__content h1 {
    font-size: clamp(34px, 9vw, 44px);
  }

  .window--welcome .welcome__mark {
    width: min(60%, 200px);
  }
}

/*
  Terminal window variant.

  Keeps the .window > .window__bar + .window__body > .window__content
  structure. What makes it a console is not the frame but the ground: a
  green-tinted near-black panel, inset inside the window and outlined in one
  muted olive line, so it reads as a screen the application is showing you
  rather than as the window's own background.

  It is also the one window that does not identify itself in amber. Phosphor
  is the colour of a thing that is running, and a terminal is the only window
  here that is running something.
*/
.window--terminal {
  background: var(--surface);
}

.window--terminal .window__bar {
  background: var(--surface-sunken);
}

.window--terminal .window__title {
  color: var(--phosphor);
}

.window--terminal .window__gem {
  background: var(--olive-deep);
}

.window--terminal.is-focused .window__gem {
  background: var(--phosphor);
}

.window--terminal .window__body {
  background: var(--surface);
}

.window--terminal .window__content {
  inset: 0;
  overflow: hidden;
  padding: 10px;
  background: var(--surface);
}

.console-module {
  overflow: auto;
  border: 1px solid var(--oxidized-olive);
  background: var(--console);
  color: var(--terminal-green);
  font-family: var(--font-terminal);
}

.crt {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-image: radial-gradient(ellipse at 50% 42%, rgba(127,174,155,.07), transparent 64%);
}

.crt__boot {
  position: absolute;
  inset: 0;
  z-index: 2;
  margin: 0;
  padding: 16px 18px;
  overflow: hidden;
  color: var(--phosphor);
  font-family: var(--font-terminal);
  font-size: 17px;
  line-height: 1.5;
  letter-spacing: .01em;
  text-shadow: 0 0 6px rgba(127,174,155,.34);
  white-space: pre-wrap;
}

.crt__boot[hidden] {
  display: none;
}

.crt__cursor {
  display: inline-block;
  width: .55em;
  height: 1em;
  vertical-align: text-bottom;
  background: var(--phosphor);
  animation: crt-blink 900ms steps(1) infinite;
}

@keyframes crt-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.crt__screen {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--console);
  opacity: 0;
  transition: opacity 260ms ease-out;
}

.crt__screen.is-live {
  opacity: 1;
}

.crt__scanlines,
.crt__glare {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.crt__scanlines {
  background: repeating-linear-gradient(
    180deg,
    rgba(0,0,0,.18) 0px,
    rgba(0,0,0,.18) 1px,
    transparent 1px,
    transparent 3px
  );
  mix-blend-mode: multiply;
}

.crt__glare {
  background: radial-gradient(ellipse at 50% 50%, transparent 62%, rgba(0,0,0,.34) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .crt__cursor {
    animation: none;
  }

  .crt__screen {
    transition: none;
  }
}

/*
  Vault puzzle: the punched tape and the door lock.

  Both windows keep the standard .window structure. The tape used to be
  painted as the physical strip from the room — fluorescent stock, graphite
  perforations — but it is a readout inside a window, not an object on a
  table, so it is rendered as one: a sunken data strip with lit punches. The
  room keeps the prop; the software shows the reading.
*/
:root {
  --tape-face: var(--surface-sunken);
  --tape-edge: var(--edge-soft);
  --tape-hole: var(--accent-lit);
  --tape-roller: var(--oxidized-olive);
  --plate-amber: var(--accent);
  --plate-amber-dim: #4E4A44;
  --plate-dark: var(--console);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.tape {
  display: grid;
  gap: 14px;
  justify-items: center;
}

.tape__intro,
.tape__legend {
  margin: 0;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
}

.tape__legend {
  font-size: 12px;
}

/* The strip itself: rollers top and bottom, sprocket edges down the sides. */
.tape__grid {
  border-collapse: collapse;
  border-top: 5px solid var(--tape-roller);
  border-bottom: 5px solid var(--tape-roller);
  padding: 0;
  background:
    repeating-linear-gradient(180deg,
      var(--tape-edge) 0 3px, transparent 3px 11px) left / 6px 100% no-repeat,
    repeating-linear-gradient(180deg,
      var(--tape-edge) 0 3px, transparent 3px 11px) right / 6px 100% no-repeat,
    var(--tape-face);
  box-shadow: inset 0 0 0 1px var(--edge-soft);
  color: var(--tape-hole);
  font-family: var(--font-terminal);
}

.tape__grid th,
.tape__grid td {
  padding: 6px 13px;
  text-align: center;
}

.tape__grid thead th {
  border-bottom: 1px solid var(--edge-soft);
  color: var(--ink-dim);
  font-size: 17px;
  letter-spacing: .04em;
}

.tape__grid tbody th {
  border-right: 1px solid var(--edge-soft);
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
}

.tape__grid td {
  font-size: 20px;
  line-height: 1;
  color: var(--edge-soft);
  opacity: 1;
}

/* A punched hole is the signal; a blank stays deliberately faint. */
.tape__grid td.is-punched {
  color: var(--tape-hole);
  opacity: 1;
  text-shadow: none;
}

.window--lock {
  background: var(--surface);
}

.window--lock .window__bar {
  background: var(--surface-sunken);
}

.window--lock .window__title,
.window--lock .window__gem {
  color: var(--accent-lit);
}

.window--lock .window__gem {
  background: var(--edge-soft);
}

.window--lock.is-focused .window__gem {
  background: var(--accent);
}

.window--lock .window__body {
  background: var(--surface);
}

.window--lock .window__content {
  inset: 0;
  padding: 16px;
  border: 0;
  background: var(--surface);
}

.lock {
  display: grid;
  gap: 14px;
  justify-items: center;
  padding: 4px 0;
}

.lock__display {
  display: flex;
  gap: 8px;
  margin: 0;
}

.lock__slot {
  display: grid;
  place-items: center;
  width: 42px;
  height: 52px;
  border: 1px solid var(--edge-soft);
  background: var(--console);
  box-shadow: inset 1px 1px 0 var(--relief-dark);
  color: var(--plate-amber-dim);
  font-family: var(--font-terminal);
  font-size: 32px;
  line-height: 1;
}

.lock__slot.is-filled {
  color: var(--accent-lit);
  text-shadow: none;
}

.lock__keys {
  display: grid;
  grid-template-columns: repeat(3, 56px);
  gap: 8px;
  justify-content: center;
}

/* Zero sits under the 8, keeping the familiar keypad shape. */
.lock__key:last-child {
  grid-column: 2;
}

.lock__key,
.lock__action {
  border: 1px solid var(--edge);
  border-radius: 0;
  background: var(--surface-raised);
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark);
  color: var(--ink);
  cursor: pointer;
  font-family: var(--font-ui);
  font-weight: 600;
  transition: background 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
}

.lock__key {
  height: 48px;
  font-family: var(--font-terminal);
  font-size: 26px;
  line-height: 1;
}

.lock__key:hover,
.lock__action:hover {
  border-color: var(--edge-strong);
  background: #454A51;
  color: var(--accent-lit);
}

.lock__key:active,
.lock__action:active {
  box-shadow:
    inset 1px 1px 0 var(--relief-dark),
    inset -1px -1px 0 var(--relief-light);
  transform: none;
}

.lock__actions {
  display: flex;
  gap: 8px;
}

.lock__action {
  padding: 9px 16px;
  font-size: 14px;
}

.lock__action--open {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--screen);
}

.lock__action--open:hover {
  border-color: var(--accent-lit);
  background: var(--accent-lit);
  color: var(--screen);
}

.lock__action:disabled {
  cursor: default;
  filter: grayscale(.6);
  opacity: .6;
  transform: none;
}

/*
  Scoped to the window because .window__content p sets the body ink colour,
  which outranks a lone .lock__note.
*/
.window--lock .lock__note {
  min-height: 2.6em;
  margin: 0;
  padding-inline: 10px;
  color: var(--accent-lit);
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.4;
  text-align: center;
}

.lock.is-rejected {
  animation: lock-reject 260ms ease-in-out;
}

@keyframes lock-reject {
  0%, 100% { transform: translateX(0); }
  22% { transform: translateX(-7px); }
  55% { transform: translateX(6px); }
  80% { transform: translateX(-3px); }
}

@media (prefers-reduced-motion: reduce) {
  .lock.is-rejected {
    animation: none;
  }

  .lock__key:active,
  .lock__action:active {
    transform: none;
  }
}

/*
  Mail window variant (`hablemos`).

  Same structure and same titlebar family as every other window.

  The layout follows what a desktop mail client actually does when you hit
  compose — send button and sender on one row, the addressed headers under
  it, a format bar, then the field you write in. That field is the only
  sunken surface in the window, which is the whole distinction being drawn:
  everything above it reports, and only it accepts typing.

  Each strip spans the full width because `.window__content` drops its own
  padding here and every row supplies its own.
*/
.window--correo .window__content {
  display: flex;
  flex-direction: column;
  padding: 0;
}

.window--correo .contact-form {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  gap: 0;
  margin-top: 0;
}

/* Send row: the action, and to its right whoever is sending. */

.mail__send-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 9px 12px;
  border-bottom: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
}

.contact-form .mail__send {
  flex: 0 0 auto;
  min-height: 30px;
  padding: 5px 15px;
  border-width: 1px;
  font-size: 13px;
}

.mail__send::before {
  content: "✉";
  margin-right: 8px;
}

.contact-form .mail__from {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.mail__sigil {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border: 0;
  background: var(--accent);
  transform: none;
}

/* The one real field up here: who the reply goes back to. */
.contact-form .mail__input {
  min-width: 0;
  padding: 3px 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: var(--ink);
  font-size: 14px;
}

.contact-form .mail__input:focus-visible {
  outline-offset: -1px;
}

/* Addressed header rows */

.mail__headers {
  margin: 0;
  border-bottom: 1px solid var(--edge-soft);
  background: var(--surface);
}

.mail__row {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr);
  align-items: baseline;
  gap: 10px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--edge-soft);
}

.mail__row:last-child {
  border-bottom: 0;
}

.mail__label {
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .1em;
}

.mail__value {
  min-width: 0;
  overflow: hidden;
  color: var(--ink-soft);
  font-family: var(--font-content);
  font-size: 14px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Format bar */

.mail__format {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  padding: 5px 11px;
  border-bottom: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
}

.mail__format-key {
  display: inline-flex;
  width: 28px;
  height: 25px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--edge-soft);
  background: transparent;
  color: var(--ink-soft);
  font-family: var(--font-content);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: background 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
}

.mail__format-key:hover {
  border-color: var(--edge-strong);
  background: var(--surface-raised);
  color: var(--ink);
}

.mail__format-key[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--screen);
}

/* The one field that accepts typing */

.mail__editor {
  flex: 1 1 auto;
  min-height: 150px;
  overflow-y: auto;
  margin: 0;
  padding: 14px 14px 20px;
  background: var(--surface-sunken);
  color: var(--ink);
  font-family: var(--font-content);
  font-size: 15px;
  line-height: 1.62;
}

.mail__editor:empty::before {
  content: attr(data-placeholder);
  color: var(--ink-dim);
}

.mail__editor:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.window__content .mail__editor p {
  margin: 0 0 .7em;
  color: inherit;
}

.mail__editor ul,
.mail__editor ol {
  margin: 0 0 .7em;
  padding-left: 1.5em;
}

.mail__editor li {
  margin-bottom: .18em;
}

/* Only speaks when the send had something to report. */

.mail__status {
  margin: 0;
  padding: 9px 12px;
  border-top: 1px solid var(--edge-soft);
  background: var(--surface);
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 13px;
}

.mail__status:empty {
  display: none;
}

/*
  The escape hatch from the form. It sits outside the composer fiction on
  purpose: someone who does not trust a web form, or who wants a thread in
  their own inbox, needs an address and not another textarea.
*/
.mail__direct {
  margin: 0;
  padding: 8px 12px;
  border-top: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 12px;
}

.mail__direct a {
  color: var(--ink-soft);
  font-weight: 600;
}

@media (max-width: 760px) {
  .mail__row {
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
    padding: 7px 12px;
  }
}

/*
  Archive window variant (`archivo`), built as a reader app.

  Two panes: a sidebar of sections, and a pane holding either the list of
  articles or one article being read.

  This is the second window to override the scrolling of .window__content, for
  the same kind of reason as the terminal: a two-pane app scrolls its content
  pane, not its chrome. The sidebar has to stay put while the list moves, so
  .window__content stops scrolling and .reader__pane takes over.
*/
.window--archivo .window__content {
  overflow: hidden;
  padding: 0;
}

.reader {
  display: grid;
  grid-template-columns: 212px minmax(0, 1fr);
  height: 100%;
  min-height: 0;
  background: var(--surface);
}

/* Sidebar */

.reader__nav {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  padding: 0 0 14px;
  border-right: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
}

.reader__identity {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--edge-soft);
}

.reader__sigil {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border: 0;
  background: var(--accent);
  transform: none;
}

.reader__identity-text {
  display: grid;
  min-width: 0;
  line-height: 1.15;
}

.reader__identity-text strong {
  color: var(--ink);
  font-family: var(--font-brand);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .04em;
}

.reader__identity-text small {
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 12px;
}

.reader__group {
  margin: 14px 14px 6px;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .12em;
}

.reader__sections {
  margin: 0;
  padding: 0;
  list-style: none;
}

.reader__section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 14px;
  border-left: 2px solid transparent;
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 14px;
  text-decoration: none;
  transition: background 120ms ease-out, color 120ms ease-out;
}

.reader__section:hover {
  background: var(--surface-raised);
  color: var(--ink);
}

.reader__section.is-current {
  border-left-color: var(--accent);
  background: var(--surface-raised);
  color: var(--ink);
  font-weight: 600;
}

.reader__count {
  flex: 0 0 auto;
  min-width: 22px;
  padding: 0 6px;
  border: 1px solid var(--edge-soft);
  background: transparent;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
  text-align: center;
}

.reader__section.is-current .reader__count {
  border-color: var(--accent);
  background: transparent;
  color: var(--accent-lit);
}

/* The deliberate choice, explained where someone can actually see it. */
.reader__note {
  margin: auto 14px 0;
  padding-top: 14px;
  border-top: 1px solid var(--edge-soft);
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 1.45;
}

/* Content pane */

.reader__pane {
  min-height: 0;
  overflow-y: auto;
  padding: 22px 26px 28px;
  scrollbar-width: thin;
  scrollbar-color: var(--edge) var(--surface-sunken);
}

.reader__head {
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--edge-soft);
}

.window__content .reader__head h2 {
  max-width: none;
  margin-bottom: 6px;
  font-size: clamp(26px, 2.6vw, 34px);
}

.window__content .reader__head .lead {
  max-width: 62ch;
  margin-bottom: 0;
}

.entry-list {
  display: grid;
  gap: 12px;
}

.entry {
  padding: 12px 14px;
  border: 1px solid var(--edge-soft);
  border-left-width: 2px;
  background: var(--surface-raised);
}

.entry--external {
  border-left-color: var(--accent);
  background: var(--surface-raised);
}

.entry__title {
  display: inline-block;
  margin-bottom: 5px;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.28;
}

.window__content .entry__excerpt {
  margin: 0 0 7px;
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.5;
}

.window__content .entry__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
  letter-spacing: .03em;
}

.entry__tag {
  padding: 1px 7px;
  border: 1px solid var(--edge-soft);
  background: transparent;
}

.reader__feed-status {
  margin: 0 0 12px;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
}

.reader__feed [data-archive-feed-items] {
  display: grid;
  gap: 12px;
}

.window__content .reader__empty {
  margin: 0;
  padding: 26px 0;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 14px;
}

/* Reading view */

.reader__back {
  margin-bottom: 16px;
  padding: 5px 12px;
  border: 1px solid var(--edge);
  background: var(--surface-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow:
    inset 1px 1px 0 var(--relief-light),
    inset -1px -1px 0 var(--relief-dark);
  transition: background 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
}

.reader__back:hover {
  border-color: var(--edge-strong);
  background: #454A51;
  color: var(--accent-lit);
  transform: none;
}

/*
  The article arrives as the markup of its own page, so these rules mirror
  articulo.css for the elements a note actually uses. They are scoped to the
  sheet, so nothing here leaks into the rest of the desktop.
*/
.reader__sheet {
  padding: 24px 26px 28px;
  border: 1px solid var(--edge-soft);
  background: var(--surface);
}

.reader__sheet:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.window__content .reader__sheet h1 {
  max-width: none;
  margin: 0 0 8px;
  font-size: clamp(26px, 3vw, 36px);
}

.window__content .reader__sheet h2 {
  max-width: none;
  margin: 30px 0 10px;
  font-size: 21px;
}

.window__content .reader__sheet p {
  margin: 0 0 15px;
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}

.reader__sheet .note-eyebrow {
  margin: 0 0 10px;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .14em;
}

.window__content .reader__sheet .note-meta {
  margin: 0 0 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--edge-soft);
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 13px;
}

.reader__sheet ul {
  margin: 0 0 15px;
  padding-left: 22px;
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}

.reader__sheet li {
  margin-bottom: 7px;
}


.reader__sheet code {
  padding: 1px 5px;
  border: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
  color: var(--phosphor);
  font-family: var(--font-terminal);
  font-size: 1.02em;
}

.reader__sheet pre {
  margin: 0 0 18px;
  scrollbar-width: thin;
  scrollbar-color: var(--edge) var(--console);
  padding: 13px 15px;
  overflow-x: auto;
  border: 1px solid var(--edge-soft);
  background: var(--console);
  color: var(--phosphor);
  font-family: var(--font-terminal);
  font-size: 14px;
  line-height: 1.5;
}

.reader__sheet pre code {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font-size: 1em;
}

.reader__sheet .note-aside {
  margin: 0 0 18px;
  padding: 12px 15px;
  border-left: 2px solid var(--accent);
  background: var(--surface-sunken);
}

.reader__sheet .note-aside p:last-child {
  margin-bottom: 0;
}

.window__content .reader__permalink {
  margin: 16px 0 0;
  font-family: var(--font-ui);
  font-size: 13px;
}

@media (max-width: 760px) {
  /* One column: the sections become a strip above the pane. */
  .reader {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .reader__nav {
    overflow: visible;
    /* No identity block here to hold the first label clear of the frame. */
    padding: 8px 0;
    border-right: 0;
    border-bottom: 1px solid var(--edge-soft);
  }

  .reader__identity,
  .reader__note {
    display: none;
  }

  .reader__group {
    margin: 10px 12px 4px;
  }

  .reader__sections {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0 12px;
  }

  .reader__section {
    padding: 5px 10px;
    border: 1px solid var(--edge-soft);
    border-left-width: 2px;
  }

  .reader__pane {
    padding: 16px 14px 20px;
  }

  .reader__sheet {
    padding: 18px 16px 22px;
  }
}

/*
  Manual window variant (`manual`), built as a help viewer.

  Toolbar, a contents/search pane and one page at a time — the shape of every
  help file that shipped on a CD. It shares the two-pane idea with `archivo`
  but not its rules: here the tree is the whole navigation, it collapses, and
  the pane below the toolbar is what scrolls.

  Everything on the toolbar does something. There is no Refresh and no Stop,
  because a control that does nothing is the one thing a window about our
  standards must not demonstrate.
*/
.window--manual .window__content {
  overflow: hidden;
  padding: 0;
}

.manual {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  height: 100%;
  min-height: 0;
  background: var(--surface);
}

/* Toolbar */

.manual__toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
}

.manual__tool {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border: 1px solid var(--edge-soft);
  background: var(--surface-raised);
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
}

.manual__tool:hover:not(:disabled) {
  border-color: var(--edge-strong);
  background: #454A51;
  color: var(--ink);
}

.manual__tool:active:not(:disabled) {
  box-shadow: inset 1px 1px 0 var(--relief-dark);
  transform: none;
}

/*
  Greyed out when there is nowhere to go, like the original.

  WCAG exempts inactive controls from contrast, and the obvious reading of
  "disabled" is to drop it to --edge, which measures 2.58 here. But a Back
  button you cannot read is not telling you it is disabled, it is telling you
  nothing: --edge-strong holds 3.51, still half the 8.86 of an enabled tool,
  so the state reads without the label disappearing.
*/
.manual__tool:disabled {
  border-color: var(--edge-soft);
  background: transparent;
  color: var(--edge-strong);
  cursor: default;
}

.manual__tool-divider {
  width: 1px;
  height: 18px;
  margin: 0 3px;
  background: var(--edge-soft);
}

/* Panes */

.manual__panes {
  display: grid;
  grid-template-columns: 246px minmax(0, 1fr);
  min-height: 0;
}

.manual.is-contents-hidden .manual__panes {
  grid-template-columns: minmax(0, 1fr);
}

/*
  A class that sets `display` outranks the browser's own [hidden] rule, so
  hiding this pane needs saying out loud or the button does nothing.
*/
.manual__nav[hidden] {
  display: none;
}

.manual__nav {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--edge-soft);
  background: var(--surface-sunken);
}

.manual__tabs {
  display: flex;
  gap: 2px;
  padding: 7px 8px 0;
  border-bottom: 1px solid var(--edge-soft);
}

.manual__tab {
  padding: 4px 13px;
  border: 1px solid var(--edge-soft);
  border-bottom: 0;
  background: transparent;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.manual__tab[aria-selected="true"] {
  position: relative;
  bottom: -1px;
  border-color: var(--edge);
  background: var(--surface);
  color: var(--ink);
}

.manual__tabpanel {
  min-height: 0;
  overflow-y: auto;
  padding: 10px 8px 14px;
}

/* Contents tree */

.manual__tree,
.manual__tree ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.manual__tree ul {
  margin-left: 15px;
  border-left: 1px solid var(--edge-soft);
}

.manual__topic-link {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 8px;
  border-left: 2px solid transparent;
  color: var(--ink-soft);
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.3;
  text-decoration: none;
  transition: background 120ms ease-out, color 120ms ease-out;
}

.manual__topic-link:hover {
  background: var(--surface-raised);
  color: var(--ink);
}

.manual__topic-link--book {
  margin-top: 8px;
  font-weight: 600;
}

.manual__topic-link.is-current {
  border-left-color: var(--accent);
  background: var(--surface-raised);
  color: var(--ink);
}

/* A page marker, and a book marker for the topic fronts. */
.manual__icon {
  flex: 0 0 auto;
  width: 8px;
  height: 10px;
  border: 1px solid var(--edge);
  background: transparent;
}

.manual__icon--book {
  width: 12px;
  height: 10px;
  border-color: var(--accent);
  background: var(--accent);
}

.manual__topic-link.is-current .manual__icon {
  border-color: var(--ink);
}

/* Search */

.manual__search {
  width: 100%;
  padding: 6px 9px;
  border: 1px solid var(--edge-soft);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
  box-shadow: inset 1px 1px 0 var(--relief-dark);
}

.manual__search-status {
  margin: 9px 0 0;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 11px;
}

.manual__results {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.manual__result {
  display: block;
  margin-bottom: 6px;
  padding: 8px 9px;
  border: 1px solid var(--edge-soft);
  border-left: 2px solid var(--accent);
  background: var(--surface-raised);
  color: var(--ink);
  text-decoration: none;
}

.manual__result:hover {
  border-color: var(--edge-strong);
  border-left-color: var(--accent-lit);
}

.manual__result strong {
  display: block;
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.25;
}

.manual__result-book {
  display: block;
  margin-bottom: 4px;
  color: var(--ink-dim);
  font-family: var(--font-terminal);
  font-size: 10px;
  letter-spacing: .06em;
}

.manual__result small {
  display: block;
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.45;
}

.manual__result mark {
  padding: 0 2px;
  background: var(--accent);
  color: var(--screen);
}

/* The page being read */

.manual__topic {
  min-height: 0;
  overflow-y: auto;
  padding: 22px 28px 30px;
  scrollbar-width: thin;
  scrollbar-color: var(--edge) var(--surface-sunken);
}

.manual__topic:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.window__content .manual__page h2 {
  max-width: 22ch;
  margin-bottom: 16px;
  font-size: clamp(25px, 2.5vw, 33px);
}

.window__content .manual__page .lead {
  max-width: 62ch;
}

@media (max-width: 760px) {
  /* The tree costs too much width here, so it starts collapsed and the
     toolbar button is how you get it back. */
  .manual__panes {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .manual__nav {
    max-height: 52%;
    border-right: 0;
    border-bottom: 1px solid var(--edge-soft);
  }

  .manual__toolbar {
    flex-wrap: wrap;
    gap: 5px;
  }

  .manual__tool {
    padding: 5px 9px;
    font-size: 12px;
  }

  .manual__tool-divider {
    display: none;
  }

  .manual__topic {
    padding: 16px 14px 20px;
  }
}

/*
  Printing a page of the manual.

  A client who wants our standards on paper should get the standards, not a
  screenshot of a fake desktop. Everything but the open page is dropped, and
  the page is re-set for ink: no sheet tint, no shadows, real black on white.
*/
@page {
  margin: 18mm 16mm;
}

@media print {
  html,
  body {
    height: auto;
    overflow: visible;
    background: #fff;
  }

  .topbar,
  .dock,
  .start-menu,
  .room-layer,
  .window:not(.window--manual),
  .window--manual .window__bar,
  .window--manual .window__body::before,
  .manual__toolbar,
  .manual__nav {
    display: none !important;
  }

  .os-shell,
  .desktop,
  .window-layer,
  .window--manual,
  .window--manual .window__body,
  .window--manual .window__content,
  .manual,
  .manual__panes,
  .manual__topic {
    position: static !important;
    display: block !important;
    width: auto !important;
    height: auto !important;
    max-height: none !important;
    inset: auto !important;
    overflow: visible !important;
    padding: 0 !important;
    border: 0 !important;
    background: #fff !important;
    box-shadow: none !important;
    transform: none !important;
  }

  .manual__page,
  .manual__page *,
  .manual__page .file-row small,
  .manual__page .quiet {
    color: #000 !important;
  }

  /* The row bullet is decoration on screen and a smudge on paper. */
  .manual__page .file-row {
    display: block !important;
    padding: 8px 0 !important;
  }

  .manual__page .file-row__icon {
    display: none !important;
  }

  .manual__page .principles li {
    display: block !important;
    padding: 8px 0 !important;
  }

  .manual__page .principles li > span {
    display: block !important;
    margin-bottom: 2px;
  }

  .manual__page .file-list {
    border: 0 !important;
    background: transparent !important;
  }

  /* A line the width of the paper is a line nobody finishes reading. */
  .manual__page {
    max-width: 46em;
  }

  .manual__page .eyebrow {
    margin-bottom: 6px;
    font-size: 11pt;
  }

  .window__content .manual__page h2 {
    max-width: none;
    font-size: 20pt;
  }

  .file-row,
  .principles li {
    break-inside: avoid;
    border-color: #000 !important;
    background: transparent !important;
    box-shadow: none !important;
  }

  /* The call to action is a button on screen and noise on paper. */
  .manual__page .button {
    display: none !important;
  }
}
