/* octo note — typesafe.ai-inspired: one family, sub-1 display leading,
   mono micro-labels, wide body tracking. Dark, minimal, no big boxes. */

@font-face {
  font-family: 'Host Grotesk';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/static/fonts/host-grotesk-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Host Grotesk';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/static/fonts/host-grotesk-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url(/static/fonts/jetbrains-mono-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* TypeSafe look (2026-09-25): flat pink field, warm near-black ink,
   thin L-shaped corner brackets as framing marks. Pink/ink sampled from the
   TypeSafe logo (#f386a3 / #3a2e30). Every text colour >= 4.5:1 on the pink. */
/* `hidden` must win over any display rule (.link is display:flex, which kept
   'lock' in rooms and 'burn all' on an empty page visible). */
[hidden] { display: none !important; }

:root {
  --item-size: 21px;           /* notes, files, folders: one size */
  --bg: #f386a3;          /* TypeSafe pink */
  --drop: rgba(247, 169, 190, .9);
  --panel: #f59bb3;       /* composer, one step lighter */
  --panel-2: #f7a9be;     /* composer focused */
  --fg: #2a1e21;          /* ink, 6.7:1 */
  --dim: #3b2d30;         /* TypeSafe logo ink, 5.5:1 */
  --faint: #4d363c;       /* labels, 4.6:1 */
  --line: rgba(42, 30, 33, .20);
  --line-2: rgba(42, 30, 33, .42);
  --accent: #2a1e21;      /* bars/brackets are ink, like the logo */
  --warn: #6e1d0c;        /* 4.7:1 */
  --crit: #5c0a18;        /* 5.8:1 */
  --br: 12px;             /* bracket arm */
  --bw: 1.5px;            /* bracket stroke */
  --ease: cubic-bezier(.2, .7, .2, 1);
}

/* extra palettes: butter + cool pastels. Same ink everywhere; theme.js picks one at random. */
/* Colour changes are applied instantly (see the note on html,body above), so
   .theming no longer stretches anything. Kept as a hook for the palette drift. */

:root[data-theme="butter"] {
  --bg: #ffea99;
  --panel: #fff0b3;
  --panel-2: #fff4c4;
  --drop: rgba(255, 240, 179, .92);
}

/* cool pastels (2026-09-26). Same ink; worst text contrast 7.2:1 (periwinkle). */
:root[data-theme="mint"] { --bg: #bdeedb; --panel: #cef2e4; --panel-2: #d6f4e9; --drop: rgba(206, 242, 228, .92); }
:root[data-theme="sky"] { --bg: #bfe3f7; --panel: #cfeaf9; --panel-2: #d7eefa; --drop: rgba(207, 234, 249, .92); }
:root[data-theme="periwinkle"] { --bg: #c9cffa; --panel: #d6dbfb; --panel-2: #dee1fc; --drop: rgba(214, 219, 251, .92); }
:root[data-theme="lilac"] { --bg: #e0cdf6; --panel: #e8daf8; --panel-2: #ece0f9; --drop: rgba(232, 218, 248, .92); }
:root[data-theme="peach"] { --bg: #ffd3bd; --panel: #ffdece; --panel-2: #ffe4d6; --drop: rgba(255, 222, 206, .92); }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  /* NO colour transition here. A custom-property-driven colour (background-color OR
     color) under a long transition does not settle in Chromium: the transition
     starts and the computed value stops updating, so the page keeps the old colour.
     Both the palette drift and the light/dark flip therefore apply instantly. */
  color: var(--fg);
  font-family: 'Host Grotesk', Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

::selection { background: var(--fg); color: var(--bg); }

body {
  min-height: 100svh;
  display: flex;
  justify-content: center;
  padding: max(9vh, 44px) 28px calc(44px + env(safe-area-inset-bottom));
}

/* ---------- corner brackets ----------
   Reusable: any element with .brackets gets four L-marks at its corners.
   Four 12px corner gradients, no extra DOM. */
.brackets { position: relative; }
.brackets::before {
  content: "";
  position: absolute;
  inset: var(--bo, -8px);
  pointer-events: none;
  --c: var(--bc, var(--fg));
  background:
    linear-gradient(var(--c), var(--c)) top left    / var(--br) var(--bw),
    linear-gradient(var(--c), var(--c)) top left    / var(--bw) var(--br),
    linear-gradient(var(--c), var(--c)) top right   / var(--br) var(--bw),
    linear-gradient(var(--c), var(--c)) top right   / var(--bw) var(--br),
    linear-gradient(var(--c), var(--c)) bottom left / var(--br) var(--bw),
    linear-gradient(var(--c), var(--c)) bottom left / var(--bw) var(--br),
    linear-gradient(var(--c), var(--c)) bottom right/ var(--br) var(--bw),
    linear-gradient(var(--c), var(--c)) bottom right/ var(--bw) var(--br);
  background-repeat: no-repeat;
  transition: inset .35s var(--ease), opacity .35s var(--ease);
}

.wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 34rem;
  display: flex;
  flex-direction: column;
  gap: 30px;
}

/* ---------- type ---------- */

.micro {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 400;
  font-size: 13px;
  line-height: 1.2;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* ---------- composer ---------- */

.composer {
  background: var(--panel);
  transition: background .25s var(--ease);
  animation: rise .5s .05s var(--ease) both;
  --bo: -9px;
}
.composer:focus-within { background: var(--panel-2); --bo: -6px; }
.composer.drag { background: var(--panel-2); --bo: -4px; }

textarea {
  display: block;
  width: 100%;
  min-height: 64px;
  max-height: 46vh;
  padding: 16px 16px 6px;
  border: 0;
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 18px;                 /* >=16px = no iOS zoom on focus */
  font-weight: 450;
  line-height: 1.45;
  letter-spacing: .01em;
  resize: none;
  outline: none;
  overflow-y: auto;
  caret-color: var(--fg);
}
textarea::placeholder { color: var(--faint); opacity: .8; letter-spacing: .03em; }

.composer-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px 14px 16px;
}
.composer-actions { display: flex; align-items: center; gap: 8px; }

.btn {
  appearance: none;
  border: var(--bw) solid var(--fg);
  border-radius: 0;
  background: var(--fg);
  color: var(--bg);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: 0 15px;
  height: 38px;
  min-width: 34px;
  cursor: pointer;
  transition: transform .18s var(--ease), background .18s var(--ease),
              color .18s var(--ease), opacity .18s;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(.985); }
.btn:disabled { opacity: .4; cursor: default; transform: none; }
.btn.ghost { background: transparent; color: var(--fg); }
.btn.ghost:hover { background: var(--fg); color: var(--bg); }
.btn:focus-visible, .link:focus-visible { outline: var(--bw) solid var(--fg); outline-offset: 3px; }

.link {
  appearance: none;
  background: none;
  border: 0;
  padding: 0 6px;
  min-height: 30px;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  color: var(--faint);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.link:hover { color: var(--fg); }

.drop-hint {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--drop);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s var(--ease);
}
.composer.drag .drop-hint { opacity: 1; }
.drop-hint span {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg);
}

.bar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 30px;
  margin-top: -6px;
}
#burn:hover { color: var(--crit); }

/* ---------- items ---------- */

.items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.items:empty { display: none; }

.item {
  position: relative;
  padding: 16px 0 17px;
  border-top: 1px solid var(--line);
  animation: rise .4s var(--ease) both;
  overflow: hidden;
}
.item:last-child { border-bottom: 1px solid var(--line); }
.item.dying { animation: fade .45s var(--ease) both; }

.item-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.item-name {
  font-size: var(--item-size);
  font-weight: 450;
  line-height: 1.36;
  letter-spacing: .01em;
  word-break: break-word;
  min-width: 0;
}
.item-body {
  margin: 0;
  font-size: var(--item-size);
  font-weight: 450;
  line-height: 1.36;
  letter-spacing: .005em;
  color: var(--fg);
  white-space: pre-wrap;
  overflow-wrap: break-word;       /* break inside a word only if it can't fit a line on its own */
  max-height: calc(1.36em * 9);
  overflow: hidden;
  font-feature-settings: "ss01", "cv11";
}
.autolink {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .16em;
  text-decoration-color: var(--line-2);
  transition: text-decoration-color .2s var(--ease);
  overflow-wrap: anywhere;         /* a link moves to its own line first; only a link longer
                                      than the line is split mid-way */
}
.autolink:hover { text-decoration-color: var(--fg); }

.item-body.clamped {
  cursor: pointer;
  mask-image: linear-gradient(#000 72%, transparent);
  -webkit-mask-image: linear-gradient(#000 72%, transparent);
}
.item-body.open { max-height: none; mask-image: none; -webkit-mask-image: none; }

/* files inside one drop: quiet rows, no boxes */
.files { list-style: none; margin: 0; padding: 0; }
.file {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 3px 0;
  animation: rise .3s var(--ease) both;
}
.file.dying { animation: fade .3s var(--ease) both; }
.file-name {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--fg);
  font-size: var(--item-size);
  font-weight: 450;
  line-height: 1.36;
  letter-spacing: .01em;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
  transition: border-color .2s var(--ease);
}
.file-name:hover { border-bottom-color: var(--fg); }
.file-size { flex: 0 0 auto; }
.file-x {
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  line-height: 1;
  min-height: 26px;
  min-width: 26px;
  justify-content: center;
  opacity: .55;
  transition: opacity .2s var(--ease), color .2s var(--ease);
}
.file-open {
  flex: 0 0 auto;
  color: var(--faint);
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  min-height: 26px;
  padding: 0 4px;
}
.file-open:hover { color: var(--fg); }
.file:hover .file-x, .file-x:focus-visible { opacity: 1; }
.file-x:hover { color: var(--crit); }
@media (pointer: coarse) {
  .file { padding: 5px 0; }
  .file-x { opacity: 1; min-height: 34px; min-width: 34px; }
  .file-open { min-height: 34px; padding: 0 8px; }
}

/* one row, always: clock · size on the left (size gives way first), actions on the right */
.item-meta { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; margin-top: 8px; }
.item-meta .micro { white-space: nowrap; }
.item-meta .size { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--faint); }
.name-size { margin-left: 10px; color: var(--faint); white-space: nowrap; vertical-align: 2px; }
.item-meta .size::before { content: "\00b7"; margin-right: 10px; color: var(--faint); }

.clock { color: var(--fg); font-weight: 500; }
.clock.warn { color: var(--warn); }
.clock.crit { color: var(--crit); animation: pulse 1s infinite steps(1, end); }

.acts { display: flex; flex: 0 0 auto; flex-wrap: nowrap; gap: 2px; margin-left: auto; }
.acts .link { min-width: 32px; color: var(--faint); font-family: 'JetBrains Mono', monospace;
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase;
  min-height: 30px; display: inline-flex; align-items: center; padding: 0 8px; }
.acts .link:hover { color: var(--fg); }
.acts .link.kill:hover { color: var(--crit); }

/* life bar: ink on a faint ink track, flush to the item's bottom edge */
.life {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--line);
  overflow: hidden;
}
.life i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--fg);
  transform-origin: left center;
  transition: transform .25s linear, background .3s var(--ease);
}
.life i.warn { background: var(--warn); }
.life i.crit { background: var(--crit); }

/* stop-upload × next to "uploading": same family as the per-file × */
.up-state { display: inline-flex; align-items: center; gap: 6px; }
.up-x {
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  line-height: 1;
  min-height: 26px;
  min-width: 26px;
  justify-content: center;
  opacity: .7;
  transition: opacity .2s var(--ease), color .2s var(--ease);
}
.up-x:hover, .up-x:focus-visible { opacity: 1; color: var(--crit); }
@media (pointer: coarse) { .up-x { opacity: 1; min-height: 34px; min-width: 34px; } }

/* upload progress: deliberately unlike the life bar (2 px, solid, shrinking).
   Thicker, hatched with ink stripes that march left to right, and it GROWS.
   The fill is revealed with clip-path, not scaleX, so the stripes never
   stretch. */
.up {
  margin-top: 12px;
  height: 5px;
  background: var(--line);
  overflow: hidden;
  position: relative;
}
.up i {
  display: block;
  height: 100%;
  width: 100%;
  background-image: repeating-linear-gradient(-45deg,
    var(--fg) 0 3px, transparent 3px 6px);
  background-size: 8.4853px 100%;      /* 6 px stripe period / cos 45deg: seamless loop */
  clip-path: inset(0 100% 0 0);
  transition: clip-path .2s var(--ease);
  animation: march .6s linear infinite;
}
.up.indet i {
  clip-path: inset(0 0 0 0);
  opacity: .45;                        /* size unknown yet: stripes march, no fill */
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(30px + env(safe-area-inset-bottom));
  transform: translate(-50%, 14px);
  padding: 10px 16px;
  background: var(--fg);
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
  max-width: calc(100vw - 56px);
  text-align: center;
  z-index: 5;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.bad { background: var(--crit); color: #fbe3ea; }

/* ---------- code gate: four underscores, _ _ _ _ ----------
   Locked: only the gate shows; the notes UI isn't rendered at all. */
.gate { display: none; }
html.locked .wrap, html.locked .toast { display: none; }
html.pending .gate { visibility: hidden; }        /* no flash of ____ for unlocked browsers */
html.locked .gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  margin-top: 18vh;
  width: 100%;
}
.gate-box {
  position: relative;
  display: block;
  padding: 10px 14px;
  cursor: text;
}
.slots { display: flex; gap: 20px; }
.slots i {
  display: block;
  position: relative;
  width: 34px;
  height: 46px;
  border-bottom: 2px solid var(--line-2);
  transition: border-color .2s var(--ease);
}
.slots i.on { border-bottom-color: var(--fg); }          /* filled */
.slots i.on::after {                                      /* a dot, never the digit */
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: var(--fg);
  animation: rise .18s var(--ease);
}
.slots i.cur { border-bottom-color: var(--fg); animation: pulse 1.1s ease-in-out infinite; }
.gate.bad .slots { animation: shake .36s var(--ease); }
.gate.bad .slots i { border-bottom-color: var(--crit); }
.gate.wait .slots i { border-bottom-color: var(--line); animation: none; }
/* the real input sits invisibly on top of the slots: native keyboard, paste,
   autofill-off, screen readers, and the whole area is the hit target */
#pin {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: 0;
  padding: 0;
  font-size: 16px;            /* no iOS zoom-on-focus */
  color: transparent;
  caret-color: transparent;
  background: transparent;
}
.gate-msg { min-height: 16px; text-align: center; }
.gate.bad .gate-msg { color: var(--crit); }
@keyframes shake {
  20%, 60% { transform: translateX(-7px); }
  40%, 80% { transform: translateX(7px); }
}
@media (prefers-reduced-motion: reduce) {
  .gate.bad .slots, .slots i.cur, .slots i.on::after { animation: none; }
}
.bar-links { display: inline-flex; align-items: center; gap: 4px; }
.bar-row > *, .bar-links > * { white-space: nowrap; }     /* one row, never stacked words */
#status { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#lock:hover { color: var(--fg); }
@media (max-width: 480px) {
  html.locked .gate { margin-top: 14vh; }
  .slots { gap: 16px; }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade {
  to { opacity: 0; transform: translateY(-4px); }
}
@keyframes pulse {
  50% { opacity: .35; }
}
@keyframes march {
  to { background-position: 8.4853px 0; }
}

@media (max-width: 480px) {
  :root { --br: 10px; }
  body { padding: 40px 24px calc(40px + env(safe-area-inset-bottom)); }
  :root { --item-size: 19px; }
  .wrap { gap: 26px; }
  .composer-foot { padding: 10px 10px 12px 12px; }
  .item-head { flex-direction: column; align-items: flex-start; gap: 4px; }
  .acts .link { font-size: 12px; letter-spacing: .04em; padding: 0 6px; min-width: 0; }
  .item-meta { gap: 8px; }
  .name-size { margin-left: 10px; color: var(--faint); white-space: nowrap; vertical-align: 2px; }
.item-meta .size::before { margin-right: 8px; }
}
@media (pointer: coarse) {
  .acts { gap: 0; }
  .acts .link { min-height: 36px; padding: 0 7px; }
  .link { min-height: 32px; }
}

@media (prefers-reduced-motion: reduce) {
  html, body, .composer { transition: none !important; }
  *, *::before, *::after { animation-duration: .001s !important; transition-duration: .001s !important; }
}


/* ---------- dark mode (2026-10-03) ----------
   Light/dark is a separate axis from the palette. Dark inverts the pair: a much
   darker field with warm cream ink (never pure white, same reasoning as the
   trailer card). Every palette gets a dark twin, so the random colour drift
   keeps working but stays deep.

   Specificity note: these selectors are `:root[data-mode="dark"][data-theme=X]`,
   which outranks the light `:root[data-theme=X]` rule above — no !important
   needed. The colour is applied to the root AND to body, because body is what
   paints the page. */
:root[data-mode="dark"], html[data-mode="dark"] body {
  --bg: #14110f;
  --panel: #1e1a17;
  --panel-2: #262019;
  --drop: rgba(30, 26, 23, .94);
  --fg: #f0e9df;
  --dim: #ded5c8;
  --faint: #b9ae9e;
  --line: rgba(240, 233, 223, .20);
  --line-2: rgba(240, 233, 223, .42);
  --accent: #f0e9df;
  --warn: #f0b45a;
  --crit: #ff7a6b;
}
:root[data-mode="dark"][data-theme="pink"]        { --bg: #1b1013; --panel: #251619; --panel-2: #2d1a1e; --drop: rgba(37, 22, 25, .94); }
:root[data-mode="dark"][data-theme="butter"]      { --bg: #1a170c; --panel: #241f11; --panel-2: #2c2615; --drop: rgba(36, 31, 17, .94); }
:root[data-mode="dark"][data-theme="mint"]        { --bg: #0c1714; --panel: #13211d; --panel-2: #182a24; --drop: rgba(19, 33, 29, .94); }
:root[data-mode="dark"][data-theme="sky"]         { --bg: #0b1418; --panel: #121e24; --panel-2: #17272f; --drop: rgba(18, 30, 36, .94); }
:root[data-mode="dark"][data-theme="periwinkle"]  { --bg: #101128; --panel: #171938; --panel-2: #1d2044; --drop: rgba(23, 25, 56, .94); }
:root[data-mode="dark"][data-theme="lilac"]       { --bg: #17111f; --panel: #1f182b; --panel-2: #271e35; --drop: rgba(31, 24, 43, .94); }
:root[data-mode="dark"][data-theme="peach"]       { --bg: #1a120e; --panel: #231a14; --panel-2: #2b2019; --drop: rgba(35, 26, 20, .94); }

/* The page field is painted from the MODE ATTRIBUTE, not from var(--bg).
   Chromium does not restart a transition when only a custom property changes
   underneath a transitioned declaration (proved on the test instance: forcing
   --bg inline left body painted the old colour indefinitely). An attribute
   selector is a real declaration change, so the 1.6s fade runs — and it also
   means the paint cannot get out of step with the variables. */
/* the mode flip must be instant: a var-driven background-color under a 1.6s
   transition never settles in Chromium (the value simply stops updating).
   `.mode-swap` is added for one frame by core.js while the attribute flips. */
.mode-swap, .mode-swap body, .mode-swap .composer, .mode-swap .btn,
.mode-swap .toast, .mode-swap .drop-hint { transition: none !important; }
html[data-mode="dark"], html[data-mode="dark"] body { background-color: #14110f; color: #f0e9df; }
html[data-mode="dark"][data-theme="pink"],       html[data-mode="dark"][data-theme="pink"] body       { background-color: #1b1013; }
/* pink is the default palette, so it carries no data-theme attribute */
html[data-mode="dark"]:not([data-theme]),        html[data-mode="dark"]:not([data-theme]) body        { background-color: #1b1013; }
html[data-mode="dark"][data-theme="butter"],     html[data-mode="dark"][data-theme="butter"] body     { background-color: #1a170c; }
html[data-mode="dark"][data-theme="mint"],       html[data-mode="dark"][data-theme="mint"] body       { background-color: #0c1714; }
html[data-mode="dark"][data-theme="sky"],        html[data-mode="dark"][data-theme="sky"] body        { background-color: #0b1418; }
html[data-mode="dark"][data-theme="periwinkle"], html[data-mode="dark"][data-theme="periwinkle"] body { background-color: #101128; }
html[data-mode="dark"][data-theme="lilac"],      html[data-mode="dark"][data-theme="lilac"] body      { background-color: #17111f; }
html[data-mode="dark"][data-theme="peach"],      html[data-mode="dark"][data-theme="peach"] body      { background-color: #1a120e; }

/* buttons invert: the fill is the ink colour, so in dark it is cream on dark text */
html[data-mode="dark"] .btn       { background: #f0e9df; border-color: #f0e9df; color: #14110f; }
html[data-mode="dark"] .btn.ghost { background-color: transparent; color: #f0e9df; }
html[data-mode="dark"] .btn.ghost:hover { background-color: #f0e9df; color: #14110f; }
html[data-mode="dark"] .toast     { background-color: #f0e9df; color: #14110f; }
html[data-mode="dark"] .drop-hint { background-color: rgba(30, 26, 23, .94); }

/* icon buttons in the bar: same metric as the text links, glyph sized to match */
.link.icon { padding: 0 6px; }
.link.icon svg { display: block; transition: transform .35s var(--ease); }
.link.icon:hover svg { transform: rotate(18deg); }
@media (prefers-reduced-motion: reduce) { .link.icon svg { transition: none; } .link.icon:hover svg { transform: none; } }

/* the bar clock: same shape as the other micro labels, never shortened */
#local-clock { flex: none; color: var(--faint); letter-spacing: .08em; }
@media (pointer: coarse) { .link.icon { min-width: 34px; justify-content: center; } }

/* ---------- rooms ----------
   The room's death bar: thicker and outlined, so it never reads as an item's
   2 px life bar. It drains over the room's hour; the whole room dies at zero. */
.room-bar { display: flex; flex-direction: column; gap: 8px; animation: rise .5s var(--ease) both; }
.room-bar-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.room-label { color: var(--fg); letter-spacing: .08em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-life { height: 8px; border: 1.5px solid var(--fg); padding: 1.5px; box-sizing: border-box; }
.room-life i {
  display: block; height: 100%; width: 100%;
  background: repeating-linear-gradient(135deg, var(--fg) 0 4px, transparent 4px 7px);
  transform-origin: left center;
  transition: transform 1s linear;
}
.room-life.warn { border-color: var(--warn); }
.room-life.warn i { background: repeating-linear-gradient(135deg, var(--warn) 0 4px, transparent 4px 7px); }
.room-life.crit { border-color: var(--crit); }
.room-life.crit i { background: var(--crit); animation: pulse 1s infinite steps(1, end); }
.room-tag { letter-spacing: .08em; }
#gate-cancel { margin-top: -6px; }
#setcode { color: var(--fg); }
@media (prefers-reduced-motion: reduce) { .room-life.crit i { animation: none; } }

/* files need a room code: the button stays visible, visibly off, and says why */
#pick.off { opacity: .38; cursor: not-allowed; transform: none; }
#pick.off:hover { background: transparent; color: var(--fg); }
#room-clock { flex: none; }                 /* the name may shorten, the clock never */

/* ---------- admin box (main page, after the code) ----------
   Hairline frame, two lines of mono text, one destructive link. */
.admin {
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--line-2);
  animation: rise .5s .1s var(--ease) both;
}
.admin-head, .admin-foot { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
#admin-detail { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
#admin-burn { flex: none; }
.admin-title { color: var(--fg); letter-spacing: .12em; }
#admin-rooms { color: var(--fg); }
#admin-burn { padding: 0; }
#admin-burn:hover:not(:disabled), #admin-burn.armed { color: var(--crit); }
#admin-burn.armed { font-weight: 500; }
#admin-burn:disabled { opacity: .35; cursor: default; }
.admin-warn { margin: 0; color: var(--warn); }
