/* ============================================================================
   Siphrix console — the professional pass (loads LAST, console.html only).

   Owner verdict, 2.1.3 acceptance run: "mi se pare ca este un haos cu
   litere cu descrieri" — the HUD skin (obsidian.css) dressed every label
   in shouting mono caps, notched every button, and scanlined the page,
   so a mature audit product read like a v1 space game. This layer keeps
   the brand (teal on near-black, the same tokens) and calms everything
   else: normal-case headings, one type scale, softened shapes, steady
   table rhythm, and structure inside expanded entries.

   It lives in its OWN file, linked by console.html alone, because
   obsidian.css is shared with the docs and landing pages — restyling it
   there would redesign five pages nobody asked about — and because
   console.css / console-polish.css are linked by admin.html under the
   separate ?v=admin4 marker, which this change has no business bumping.
   Every selector here overrides by loading later; nothing renames a
   class the JS relies on.
   ============================================================================ */

/* ---- Calm the room -------------------------------------------------------
   The scanline overlay and the red LIVE lamp are the two loudest v1
   tells. Scanlines go entirely; LIVE turns green — in this product red
   is reserved for scored risk, and a permanently red lamp on the front
   page taught the eye to ignore red. */
body::after { display: none; }
.live-ind { color: var(--allow); }
.live-ind i { background: var(--allow); box-shadow: 0 0 8px var(--allow); }

/* ---- One type hierarchy --------------------------------------------------
   Headings in sentence case, sans, tight tracking; tiny mono caps are
   kept ONLY where they label data (table heads, section bands), at a
   civil letter-spacing. Prose stays prose. */
.panel-head h3, .app-top h1 { text-transform: none; letter-spacing: -.01em; }
.panel-head h3 { font-size: .95rem; font-weight: 650; }
.app-top h1 { font-size: 1.05rem; font-weight: 650; }
.side-label { letter-spacing: .12em; font-size: .62rem; }
.dtable thead th { font-size: .64rem; font-weight: 600; letter-spacing: .07em; }
.kpi-card .k-label, .kpi span { letter-spacing: .08em; font-size: .66rem; }
.wk-cell > span, .al-sec h4, .fnd-ev-head, .ff > span, .surf-kind,
.inv2-band > span:first-child { letter-spacing: .07em; }

/* ---- Shapes: soft, consistent radii --------------------------------------
   obsidian squared every corner and notched the buttons with a
   clip-path. One radius scale across the console instead. */
.panel { border-radius: 12px; }
.panel::before {
  /* Replaces the HUD corner bracket with the quiet top hairline. */
  content: ""; position: absolute; top: 0; left: 8%; right: 8%;
  width: auto; height: 1px; border: 0;
  background: linear-gradient(90deg, transparent, rgba(92,242,255,.28), transparent);
  pointer-events: none;
}
.btn {
  clip-path: none; border-radius: 8px;
  font-family: var(--font-sans); font-weight: 600;
  letter-spacing: .01em; text-transform: none; font-size: .8rem;
}
.inp, .field input, .field textarea, .field select { border-radius: 8px; }
.toast { border-radius: 10px; }
.login-card.glass { border-radius: var(--radius-lg); }
.seg, .rec-seg { border-radius: 8px; }
.side-link { border-radius: 8px; }
.side-logout { border-radius: 8px; text-transform: none; letter-spacing: .02em;
  font-family: var(--font-sans); font-size: .8rem; }
.badge { border-radius: 6px; letter-spacing: .05em; }
.kbd-hint { border-radius: 6px; }
.al-item, .al-detail { border-radius: 10px; }
.al-detail { border-radius: 0 0 10px 10px; }
.kpi-card, .kpi { border-radius: 12px; }
.wk-cell { border-radius: 10px; }
.plat-row { border-radius: 8px; }
.mach .plat-row, .mach-parts .plat-row { border-radius: 0; }

/* ---- Table rhythm --------------------------------------------------------
   One density for every table: same padding, aligned baselines, the
   hover kept but the sideways inset bar dropped — rows should read,
   not twitch. */
.dtable th, .dtable td { padding: .65rem 1.1rem; }
.panel tbody tr:hover, table.tbl tbody tr:hover { box-shadow: none; }
.dtable td { line-height: 1.5; }

/* ---- Expanded entries: lead, facts, technical ----------------------------
   The story panel used to open with one long paragraph. Structure
   instead: the deed as a lead line, the outcome as a quiet sub-line,
   the labeled facts as a card, the technical entry folded — the order
   a person actually reads an incident in. */
.act-x { padding: 1.15rem 1.3rem 1.3rem; }
.act-lead { display: flex; flex-wrap: wrap; gap: .45rem; align-items: baseline;
  margin: 0 0 .3rem; font-size: 1rem; line-height: 1.5; color: var(--ink); }
.act-lead b { font-weight: 650; }
.act-lead-where { color: var(--ink-3); font-size: .84rem; }
.act-outcome { color: var(--ink-3); font-size: .82rem; margin-bottom: .85rem; }
.act-x > .dr-kv { margin-top: .9rem; padding: .7rem .95rem;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-2); max-width: 76ch;
  display: flex; flex-direction: column; gap: .3rem; }
.dr-tech { margin-top: .9rem; }
.dr-tech > summary { cursor: pointer; padding: .3rem 0; }
.dr-tech > summary:hover { color: var(--teal); }

/* ---- The members of a folded line (items in a ×N row) -------------------- */
.act-mem-list { margin: .3rem 0 1rem; max-width: 84ch;
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: var(--bg-2); }
.act-mem-head { display: flex; justify-content: space-between; gap: .8rem;
  flex-wrap: wrap; align-items: baseline; padding: .5rem .9rem;
  border-bottom: 1px solid var(--line);
  background: var(--glass, rgba(255,255,255,.02));
  font-size: .76rem; font-weight: 600; color: var(--ink-2); }
details.act-mem summary { list-style: none; cursor: pointer;
  display: grid; grid-template-columns: 1.6rem 13rem minmax(0, 1fr) auto;
  gap: .7rem; align-items: baseline; padding: .5rem .9rem; font-size: .8rem; }
details.act-mem summary::-webkit-details-marker { display: none; }
.act-mem + .act-mem { border-top: 1px solid var(--line); }
.act-mem summary:hover { background: rgba(92,242,255,.05); }
.act-mem summary:focus-visible { outline: 2px solid var(--teal); outline-offset: -2px; }
.act-mem-n { color: var(--ink-3); font-family: var(--font-mono); font-size: .72rem; }
.act-mem-when { font-family: var(--font-mono); font-size: .76rem; color: var(--ink); }
.act-mem-why { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.act-mem-open { color: var(--teal); font-size: .72rem; opacity: 0;
  transition: opacity .15s ease; white-space: nowrap; }
.act-mem summary:hover .act-mem-open, .act-mem[open] .act-mem-open { opacity: 1; }
.act-mem-kv { padding: .4rem .9rem .8rem 3rem; border-top: 1px dashed var(--line); }
.act-mem-hit > summary { background: rgba(92,242,255,.1); }
@media (max-width: 860px) {
  details.act-mem summary { grid-template-columns: 1.4rem minmax(0, 1fr) auto; }
  .act-mem-why { grid-column: 2 / -1; }
}

/* ---- A deep-linked row, found -------------------------------------------- */
tr.act-row-hit td { animation: act-hit 2.6s ease both; }
@keyframes act-hit {
  0%, 55% { background: rgba(92,242,255,.12); }
  100% { background: transparent; }
}
@media (prefers-reduced-motion: reduce) { tr.act-row-hit td { animation: none; } }

/* ---- The filter bar steps aside while you read (Activity) ---------------- */
.fbar { max-height: 32rem; overflow: hidden;
  transition: max-height .35s var(--ease), opacity .25s ease,
    transform .3s var(--ease), padding .3s ease; }
.fbar.fbar-away { max-height: 0; padding-top: 0; padding-bottom: 0;
  opacity: 0; transform: translateY(-8px); pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .fbar { transition: none; } }

/* ---- Machines: the state in a word, and per-surface freshness ------------ */
.mach-state { display: inline-block; vertical-align: middle; margin-left: .35rem;
  font: 600 .64rem/1.7 var(--font-mono); letter-spacing: .06em;
  text-transform: uppercase; padding: 0 .55rem; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--ink-2); white-space: nowrap; }
.mach-state.st-on { color: var(--allow); border-color: rgba(62,224,137,.4);
  background: rgba(62,224,137,.08); }
.mach-state.st-off { color: var(--ink-2); border-color: var(--line-2);
  background: rgba(133,146,168,.14); }
.mach-state.st-quiet { color: var(--block); border-color: rgba(255,59,92,.4);
  background: rgba(255,59,92,.07); }
/* Surface lights: green = an entry within the last day; amber = recorded
   but idle past a day; solid red = stale past a week; hollow red = the
   record holds nothing from it. Each chip prints the actual time, so
   the colour never has to be taken on faith. */
.dot-status.idle { background: var(--abort); box-shadow: 0 0 6px rgba(255,144,64,.45); }
.dot-status.never { background: transparent; border: 2px solid var(--block);
  box-sizing: border-box; }
.surf-chip .surf-last { font-size: .76rem; }
.surf-chip.sf-fresh .surf-last { color: var(--allow); }
.surf-chip.sf-idle .surf-last { color: var(--abort); }
.surf-chip.sf-stale .surf-last, .surf-chip.sf-quiet .surf-last { color: var(--block); }
.surf-chip.sf-paused .surf-last { color: var(--ink-3); }
.surf-chip.sf-idle { border-color: color-mix(in srgb, var(--abort) 30%, var(--line)); }
.surf-chip.sf-stale { border-color: color-mix(in srgb, var(--block) 30%, var(--line)); }
.surf-chip.sf-paused .dot-status { border-color: var(--ink-3); }

/* ---- Quiet consistencies -------------------------------------------------
   Small parities the eye notices as one product: pills, chips and the
   armed states share weights; empty states lose the glyph glow; panel
   subtitles read at one size. */
.pill { font-weight: 600; }
.view-empty::before { filter: none; opacity: .6; }
.set-sec .set-sub, .cap { letter-spacing: 0; }
.panel-head .ph-actions { font-size: .74rem; }

/* ---- Fleet deployment + browser watch scope (2026-09-02) -----------------
   New Surfaces sections. Everything wears existing clothes — panels,
   badges, rec-seg segments, surf-chips — these rules only cover what
   those clothes never needed before. */
/* The pack chips in the scope panel are BUTTONS (an admin presses them);
   they must wear the same .surf-chip look as the read-only chips on a
   machine row, not the browser's default button face. */
button.surf-chip { background: transparent; font: inherit; cursor: pointer; }
button.surf-chip:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
/* The x inside a custom-site chip. */
.scope-x { background: transparent; border: 0; color: var(--ink-3);
  cursor: pointer; font-size: .72rem; padding: 0 .05rem; }
.scope-x:hover { color: var(--block); }
/* "You have turned off N of the AI sites Siphrix knows" — plain sight,
   amber: turning a pack site off is allowed, but never quiet. */
.scope-off-note { color: var(--abort); margin: .55rem 0 0; max-width: 72ch; }
/* Scope segments: a neutral selected state, and the every-site state in
   amber — wide is a state worth noticing, not a success to paint green. */
.rec-opt.cur.sel { background: rgba(92,242,255,.12); color: var(--teal); }
.rec-opt.cur.wide { background: rgba(255,144,64,.14); color: var(--abort); }
/* "active" / "watched" — the good state, coloured as the other good
   badges are (machineParts' "all recorded" wears this class too). */
.badge.ok { color: var(--allow); border-color: rgba(62,224,137,.4);
  background: rgba(62,224,137,.07); }
/* The generated push script: wide content scrolls inside its own box. */
.push-head { display: flex; gap: .8rem; align-items: center;
  justify-content: space-between; flex-wrap: wrap; margin-bottom: .45rem; }
.push-script { margin: 0; padding: .9rem 1rem; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg-1); overflow: auto; max-height: 30rem; }
.push-script code { font-family: var(--font-mono); font-size: .74rem;
  line-height: 1.55; color: var(--ink-1); white-space: pre; }

/* ============================================================================
   The v2 pass (2026-09-02). Owner's order, verbatim in spirit: "if this
   console were v1, make it v2 — design, typography, typing, selecting,
   sliding. Enterprise grade, but a non-technical kid must be able to
   use it."

   Everything below stays in THIS file for the same reason the first
   pass did: console-pro.css loads last and is linked by console.html
   alone, so nothing here can restyle the admin panel or the public
   pages, which carry their own markers. No selector renames a class
   the JS relies on; new classes (.view-lead, .skel, .cmdk-g, .num,
   .view-error, .copied, .searching) are additions, wired in
   console-app.js under the same audit50 marker.
   ============================================================================ */

/* ---- One clock for motion ------------------------------------------------
   Three durations, one easing family (theme.css --ease/--ease-out).
   Everything added in this pass reads these; nothing invents a fourth
   speed. Reduced motion is honored wholesale at the end of the file. */
:root { --d-fast: .12s; --d: .2s; --d-slow: .32s; }

/* ---- Typography: the remaining calibration -------------------------------
   The scale was set in the first pass (headings sentence-case, tiny
   mono caps only on data labels). What v1 still lacked: numbers that
   line up (tabular figures everywhere a count can change under the
   eye), one line-height for reading text, and captions that never
   letter-space. */
.dtable td, .panel tbody td, table.tbl tbody td,
.kpi-card .k-val, .wk-cell > b, .rk-val, .tl-y, .tl-sum, .tl-peak,
.act-x-count, .al-tal b, .inv2-last, .chg-n, .act-mem-when,
.act-when-clock { font-variant-numeric: tabular-nums; }
.act-story, .panel-body > p, .fnd-detail, .view-lead { line-height: 1.6; }
.cap { line-height: 1.5; letter-spacing: 0; }
.panel-head h3 { line-height: 1.35; }

/* ---- What the pointer selects wears the brand ---------------------------- */
::selection { background: rgba(92, 242, 255, .28); color: #eaf7ff; }

/* ---- The lead sentence every view opens with ----------------------------- */
.view-lead { margin: 0 0 1.1rem; font-size: .95rem; color: var(--ink-2);
  max-width: 80ch; }

/* ---- Native controls, dressed for the room -------------------------------
   The browser's default select arrow and calendar are the last pieces
   of foreign chrome on the page. appearance:none + an inline SVG caret
   for selects; color-scheme keeps the date picker's popup dark; the
   teal accent covers whatever stays native. */
select.inp, .ff > select, .panel select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5l3.5 3.5 3.5-3.5' fill='none' stroke='%238592a8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .65rem center;
  background-size: 12px; padding-right: 2.1rem;
}
input[type="date"] { color-scheme: dark; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--teal); }

/* The rule On/Off checkbox becomes a real switch: state readable from
   across the desk, satisfying to press, still the same checkbox to the
   JS and the keyboard. Green when watching — the good state here is ON. */
input.rule-toggle {
  appearance: none; -webkit-appearance: none;
  width: 34px; height: 20px; border-radius: 999px; position: relative;
  border: 1px solid var(--line-2); background: var(--bg-4); cursor: pointer;
  transition: background var(--d) ease, border-color var(--d) ease;
  vertical-align: middle;
}
input.rule-toggle::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; border-radius: 50%; background: var(--ink-3);
  transition: transform var(--d) var(--ease), background var(--d) ease;
}
input.rule-toggle:checked { background: rgba(62, 224, 137, .16);
  border-color: rgba(62, 224, 137, .5); }
input.rule-toggle:checked::after { transform: translateX(14px);
  background: var(--allow); }

/* ---- Tables: one rhythm, and numbers on the right ------------------------
   Both table families (.dtable and .panel/.tbl) used two paddings; one
   density now. Numeric columns marked .num right-align in tabular
   figures — a column of counts reads down the units digit, not down
   the first character. */
.dtable th, .dtable td,
.panel thead th, table.tbl thead th,
.panel tbody td, table.tbl tbody td { padding: .6rem 1rem; }
.dtable td, .panel tbody td, table.tbl tbody td { line-height: 1.5; }
.dtable th.num, .dtable td.num, table.tbl th.num, table.tbl td.num,
.panel th.num, .panel td.num { text-align: right; }

/* ---- Sliding: every fold opens like a drawer -----------------------------
   One entrance for everything that unfolds — folds, machine innards,
   warning cards, technical entries. Slide-and-fade from the summary it
   came from; never a jump cut. Closing is instant on purpose: opening
   is a request for attention, closing is dismissal. */
@keyframes fold-in { from { opacity: 0; transform: translateY(-4px); } }
details.inv2-fold[open] > .panel-body,
details.set-fold[open] > *:not(summary),
details.dr-tech[open] > .dr-kv,
details.al-tech[open] > .dr-kv,
.mach-parts:not(.hide),
.al-detail:not(.hide) { animation: fold-in var(--d) var(--ease) both; }

/* The folded-burst member list — the signature drawer — gets the full
   treatment: an inset shadow that reads as depth, a summary that eases
   sideways under the hand, and each member's own entry unfolding in
   place. */
.act-mem-list { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .03),
  inset 0 -10px 18px -16px rgba(0, 0, 0, .6); }
details.act-mem summary { transition: background var(--d-fast) ease,
  padding-left var(--d) var(--ease); }
details.act-mem summary:hover { padding-left: 1.05rem; }
details.act-mem[open] > summary { background: rgba(92, 242, 255, .04); }
details.act-mem[open] > .act-mem-kv { animation: fold-in var(--d) var(--ease) both; }

/* ---- The armed state, unmistakable ---------------------------------------
   armTwice's first press is a question standing on screen for six
   seconds. It now breathes: a red ring pulsing at reading pace, so the
   eye that wandered comes back to a button that is visibly asking. */
.btn.armed, .dev-del.armed, .rec-opt.armed {
  background: rgba(255, 59, 92, .08);
  animation: armed-pulse 1.1s ease-in-out infinite;
}
@keyframes armed-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 59, 92, 0); }
  50% { box-shadow: 0 0 0 4px rgba(255, 59, 92, .14); }
}

/* ---- Row actions wait quietly --------------------------------------------
   The ✕ on every row shouted at full strength all day. Present at a
   whisper, full strength when the hand (or the keyboard) arrives —
   and always full strength while armed, because an armed control must
   never fade under the finger about to confirm it. */
.plat-row .dev-del, tr[data-rid] .rule-del, .surf-chip .scope-x {
  opacity: .4; transition: opacity var(--d-fast) ease;
}
.plat-row:hover .dev-del, .plat-row:focus-within .dev-del,
.mach-head:hover .dev-del, .mach-head:focus-within .dev-del,
tr[data-rid]:hover .rule-del, tr[data-rid]:focus-within .rule-del,
.surf-chip:hover .scope-x, .surf-chip:focus-within .scope-x,
.dev-del.armed, .dev-del:focus-visible, .rule-del:focus-visible,
.scope-x:focus-visible { opacity: 1; }

/* ---- Loading: the shape of the page, not a spinner ----------------------- */
.skel { display: flex; flex-direction: column; gap: 1.4rem; }
.skel-panel { border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-2); padding: 1.25rem 1.3rem;
  display: flex; flex-direction: column; gap: .8rem; }
.skel-line { display: block; height: .85rem; border-radius: 6px;
  background: linear-gradient(90deg, rgba(92, 242, 255, .05),
    rgba(92, 242, 255, .11), rgba(92, 242, 255, .05));
  background-size: 200% 100%;
  animation: skel-sheen 1.4s ease-in-out infinite;
}
.skel-line.w40 { width: 40%; }
.skel-line.w80 { width: 80%; }
@keyframes skel-sheen { from { background-position: 120% 0; }
  to { background-position: -80% 0; } }

/* ---- An error that says what to do --------------------------------------- */
.view-empty.view-error { gap: .6rem; }
.view-empty.view-error::before { content: "⚠"; color: var(--abort); filter: none; }
.view-empty.view-error b { color: var(--ink); font-size: 1rem; }
.view-empty.view-error .btn { margin-top: .4rem; }

/* ---- The command palette, finished ---------------------------------------
   Grouped like the sidebar, recents on top, soft entrance, keycap hint. */
.cmdk { border-radius: 14px; overflow: hidden;
  box-shadow: var(--shadow-2), 0 0 80px -30px rgba(92, 242, 255, .35);
  animation: cmdk-pop var(--d) var(--ease-out) both; }
@keyframes cmdk-pop { from { opacity: 0; transform: translateY(6px) scale(.985); } }
.cmdk-wrap { backdrop-filter: blur(4px); animation: cmdk-in var(--d-fast) ease both; }
@keyframes cmdk-in { from { opacity: 0; } }
.cmdk input { padding: .85rem 1.1rem; font-size: .95rem; }
.cmdk-g { padding: .6rem 1.1rem .25rem; font: 600 .62rem/1 var(--font-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.cmdk-it { padding: .5rem 1.1rem; cursor: pointer; }
.kbd-hint { display: inline-flex; gap: .25rem; align-items: center;
  border: 0; padding: 0; background: transparent; cursor: pointer; }
.kbd-hint kbd { font: 600 .64rem/1 var(--font-mono); letter-spacing: .02em;
  color: var(--ink-3); padding: .3rem .45rem; border: 1px solid var(--line-2);
  border-bottom-width: 2px; border-radius: 6px; background: var(--bg-3); }
.kbd-hint:hover kbd { color: var(--teal); border-color: var(--line-teal); }

/* ---- Typing that answers back --------------------------------------------
   The Activity search shows a quiet "searching…" while a debounced
   query is in flight; a field that visibly does nothing for a beat
   reads as broken. Copy buttons flip to a green tick on the button
   itself (sections.css already colours .copy-btn.copied; this covers
   the plain .btn copies). */
.fb-search::after { content: "searching…"; position: absolute; right: .9rem;
  font: 500 .7rem/1 var(--font-mono); color: var(--teal); opacity: 0;
  transition: opacity var(--d-fast) ease; pointer-events: none; }
.fb-search.searching::after { opacity: .85; }
.fb-search.searching .ico { color: var(--teal);
  animation: search-pulse .9s ease-in-out infinite; }
@keyframes search-pulse { 50% { opacity: .45; } }
.btn.copied { color: var(--allow) !important;
  border-color: rgba(62, 224, 137, .5) !important; }

/* ---- Pressed states that answer the hand --------------------------------- */
.rec-opt { transition: background var(--d-fast) ease, color var(--d-fast) ease; }
.rec-opt:not(.cur):active { transform: scale(.96); }
.chip-pick { transition: background var(--d-fast) ease,
  border-color var(--d-fast) ease, color var(--d-fast) ease; }
.chip-pick:active { transform: scale(.96); }

/* ---- Calm the two loops the polish layer left running --------------------
   The KPI sheen and the top-bar aurora animated forever; permanent
   motion on a monitoring product teaches the eye to ignore motion —
   the same lesson as the permanently red lamp. The KPI corner keeps
   its quiet radial tint (what console.css always intended); the
   aurora holds still. Deliberate live motion — the Sentinel, the LIVE
   lamp, the armed pulse — keeps the meaning motion should have. */
.kpi-card::after { inset: auto -30% -60% auto; width: 120px; height: 120px;
  border-radius: 50%; transform: none; animation: none;
  background: radial-gradient(circle, rgba(92, 242, 255, .10), transparent 70%); }
.kpi-card.block::after { background: radial-gradient(circle, rgba(255, 59, 92, .10), transparent 70%); }
.kpi-card.abort::after { background: radial-gradient(circle, rgba(255, 144, 64, .10), transparent 70%); }
.app-top::after { animation: none; }

/* ---- The sign-in moment --------------------------------------------------
   One soft rise for the card, focus already in the email field (the
   markup autofocuses), and the error box keeping its reserved space so
   a wrong password never reflows the form. */
.login-card { animation: card-rise var(--d-slow) var(--ease-out) both; }
@keyframes card-rise { from { opacity: 0; transform: translateY(10px); } }

/* ---- Toast & tip bubbles, finished ---------------------------------------- */
.toast { max-width: min(92vw, 52ch); text-align: center; line-height: 1.45; }
.tipbox { border-radius: 10px; line-height: 1.5; max-width: 320px;
  font-size: .78rem; box-shadow: 0 14px 40px -14px rgba(0, 0, 0, .7); }

/* ---- Reduced motion: everything this pass added, off in one place -------- */
@media (prefers-reduced-motion: reduce) {
  .skel-line, .btn.armed, .dev-del.armed, .rec-opt.armed,
  .cmdk, .cmdk-wrap, .login-card, .fb-search.searching .ico,
  details.inv2-fold[open] > .panel-body,
  details.set-fold[open] > *:not(summary),
  details.dr-tech[open] > .dr-kv, details.al-tech[open] > .dr-kv,
  details.act-mem[open] > .act-mem-kv,
  .mach-parts:not(.hide), .al-detail:not(.hide) { animation: none; }
  input.rule-toggle, input.rule-toggle::after, .rec-opt, .chip-pick,
  details.act-mem summary { transition: none; }
  .rec-opt:not(.cur):active, .chip-pick:active { transform: none; }
}
