/* ============================================================================
   Petra Archive - product identity.

   The palette is taken from the mark itself rather than chosen alongside it:
   the navy of the wordmark and the amber of the instrument. Nothing else is
   introduced except the greys that carry them, one green for "done" and one
   red for "a person must act".

     navy   #161E66   authority, structure, every primary action
     amber  #DD8934   work in progress and attention, never alarm
     green  #1B7A4B   completion, used sparingly so it still means something
     red    #A8322D   only when somebody actually has to do something

   RESTRAINT IS THE BRIEF. No gradients, no glow, no shadowed text, no animation
   that is not reporting real progress. Confidence comes from space, alignment
   and calm wording - a survey instrument, not a developer dashboard.
   ============================================================================ */

:root{
  /* THREE ROLES, AND EACH COLOUR HAS EXACTLY ONE.
   *
   *   ORANGE  = Petra. Identity, the primary action, the active page, brand detail.
   *   BLUE    = the system working. Upload, progress, securing, processing.
   *   NEUTRAL = everything else - shell, surfaces, tables, text.
   *
   * The previous pass had navy owning the whole header and amber as the only accent,
   * which made the product read blue-first. Blue is not Petra's identity; it is what
   * Petra Archive is DOING. That distinction is the whole design.
   */
  --orange:#DD8934;
  --orange-600:#C9782A;
  --orange-700:#B96C22;
  --orange-ink:#241402;
  --orange-soft:#8A5312;

  /* Process blue. Used for motion and state, never for the shell. */
  --blue:#3E72C9;
  --blue-600:#3564B4;
  --blue-soft:#25406E;

  --navy:#161E66;
  --navy-700:#1D2878;
  --navy-300:#5C68B8;

  /* Kept as aliases so existing rules keep working while the roles move. */
  --amber:var(--orange);
  --amber-ink:var(--orange-soft);
  --green:#1B7A4B;
  --red:#A8322D;

  /* KEYBOARD FOCUS. Its own token, because it is the one colour that has to stay
     visible against every surface in the product in both themes. Browsers default
     to a near-black ring, which on the dark navy background measured about 1.0:1 -
     a keyboard user could not see where they were, which fails WCAG 2.4.7. */
  --focus:#1D2878;
  --focus-halo:rgba(255,255,255,.92);

  --ink:#131A2E;
  --ink-2:#3B455F;
  --mut:#66708A;
  --line:#E3E7F0;
  --line-2:#EEF1F7;
  --bg:#F4F6FA;
  --card:#FFFFFF;
  --plate:#FFFFFF;

  /* The shell is a deep NEUTRAL, not a brand colour. Orange sits on it. */
  --shell:#141519;
  --shell-line:rgba(255,255,255,.09);
  --shell-ink:#F3F4F6;
  --shell-mut:rgba(243,244,246,.62);

  --accent:var(--orange);
  --accent-ink:var(--orange-ink);

  --radius:14px;
  --radius-sm:9px;
  --shadow:0 1px 2px rgba(19,26,46,.04), 0 6px 20px rgba(19,26,46,.05);
  --shadow-sm:0 1px 2px rgba(19,26,46,.05);
}

@media (prefers-color-scheme: dark){
  :root{
    /* NEUTRAL, NOT NAVY. The first dark palette made every large surface navy - page
       background, cards, header, tables - so the product read as one flat block of
       brand colour, which is what "generic dashboard" looks like. Navy is now
       structure and identity; the surfaces it sits on are neutral graphite. */
    --ink:#ECEEF2; --ink-2:#C3C8D2; --mut:#8A91A0;
    --line:#272B33; --line-2:#1E222A;
    --bg:#0D0F13; --card:#15181E; --plate:#FFFFFF;
    --navy:#2A3585; --navy-700:#35429E; --navy-300:#95A1E8;
    --orange:#E39A4C; --orange-600:#D08A3C; --orange-700:#BD7A2E;
    --orange-ink:#1A0E01; --orange-soft:#F0BE85;
    --blue:#5B8EDC; --blue-600:#4A7DCB; --blue-soft:#9DBDF0;
    --accent:var(--orange); --accent-ink:var(--orange-ink);
    --green:#3FA877; --red:#E0736C; --amber:var(--orange); --amber-ink:var(--orange-soft);
    --shadow:none; --shadow-sm:none;
    --focus:#A8B4FF;
    --focus-halo:rgba(6,9,20,.92);
  }
}

*{box-sizing:border-box}
/* The HTML `hidden` attribute sets display:none from the USER-AGENT stylesheet, which
   any author rule outranks. `.modal{display:flex}` therefore defeated `hidden` and the
   dialog rendered over the application on every page load. Author-level !important is
   the fix; it must come before the rules that set display. */
[hidden]{display:none !important}

body{
  margin:0; background:var(--bg); color:var(--ink);
  font:15px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
h1{font-size:26px; line-height:1.25; letter-spacing:-.018em; font-weight:650; margin:0 0 4px}
h2{font-size:12.5px; letter-spacing:.09em; text-transform:uppercase; color:var(--mut);
   font-weight:700; margin:34px 0 12px}
h3{font-size:17px; letter-spacing:-.01em; font-weight:650; margin:0 0 6px}
p{margin:0 0 12px}
a{color:var(--accent); text-decoration:none}
a:hover{text-decoration:underline}
.sub{color:var(--mut); margin:0 0 20px}
.small{font-size:13.5px}
.tiny{font-size:12px}
.muted{color:var(--mut)}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:.92em}
.right{text-align:right}
.grow{flex:1}
.spread{display:flex; align-items:center; justify-content:space-between; gap:16px}
.row{display:flex; gap:10px; flex-wrap:wrap; align-items:center}
.hidden{display:none}

/* ---------------------------------------------------------------- the mark */
/* The logo is navy on white and has no dark variant, so it is always given a white
   plate. A mark that inverts badly is worse than a mark with a plate behind it. */
.mark{display:block; background:var(--plate); border-radius:10px; padding:10px 14px;
  box-shadow:var(--shadow-sm); line-height:0}
.mark img{display:block; height:34px; width:auto}
.mark-lg{padding:18px 26px; border-radius:14px}
.mark-lg img{height:76px}

/* ---------------------------------------------------------------- buttons */
button{font:inherit; cursor:pointer; border-radius:var(--radius-sm);
  border:1px solid transparent; padding:9px 16px; font-weight:560;
  letter-spacing:-.006em; transition:background .12s, border-color .12s, color .12s}
button:disabled{opacity:.45; cursor:default}
/* AMBER IS THE ACTION. Navy is identity and structure; the one thing on a screen
   that the employee is meant to press is the accent. The previous periwinkle came
   from a lightened navy and read as neither brand colour. */
.primary{background:var(--amber); color:#241402; border-color:var(--amber);
  font-weight:640}
.primary:hover:not(:disabled){background:#C9782A; border-color:#C9782A}
.primary:active:not(:disabled){background:#B96C22; border-color:#B96C22}
@media (prefers-color-scheme: dark){
  .primary{color:#1A0E01}
  .primary:hover:not(:disabled){background:#F0AC61; border-color:#F0AC61}
}
.ghost{background:transparent; color:var(--ink-2); border-color:var(--line)}
.ghost:hover:not(:disabled){border-color:var(--mut); color:var(--ink);
  background:var(--line-2)}
/* PROCESS: blue, and only where the button starts or concerns system activity. */
.process{background:transparent; color:var(--blue); border-color:var(--blue)}
.process:hover:not(:disabled){background:color-mix(in srgb, var(--blue) 12%, transparent)}
.danger{background:transparent; color:var(--red); border-color:var(--red)}
.danger:hover:not(:disabled){background:var(--red); color:#fff}
button.wide{width:100%; margin-top:20px}
.actions{display:flex; gap:6px; flex-wrap:wrap}
.actions button{padding:5px 11px; font-size:13px}
td .actions{justify-content:flex-end}

/* ---------------------------------------------------------------- inputs */
label{display:block; font-size:13px; font-weight:620; margin:16px 0 6px; color:var(--ink-2)}
input[type=text],input[type=password],input[type=number],textarea,select{
  width:100%; padding:10px 13px; border:1px solid var(--line); border-radius:var(--radius-sm);
  background:var(--card); color:var(--ink); font:inherit; outline:none;
  transition:border-color .12s, box-shadow .12s}
input:focus,textarea:focus,select:focus{
  border-color:var(--navy-300); box-shadow:0 0 0 3px rgba(92,104,184,.16)}
.hint{font-size:12.5px; color:var(--mut); margin-top:6px}

/* ---------------------------------------------------------------- focus ring
   ONE rule for everything focusable. Previously only text inputs had a focus
   style, so buttons, links, tabs and the navigation fell through to the browser
   default - which in dark mode drew a near-black ring on a near-black surface.
   Two layers, always: a coloured ring plus a contrasting halo, so the ring is
   visible whether the element sits on the page, on a card, or on a filled
   button. `:focus-visible`, not `:focus`, so a mouse click does not draw it. */
:where(a,button,[role=button],[role=tab],input,textarea,select,summary,[tabindex]):focus-visible{
  outline:2px solid var(--focus);
  outline-offset:2px;
  box-shadow:0 0 0 4px var(--focus-halo), 0 0 0 6px var(--focus);
  border-radius:var(--radius-sm);
}
/* Windows High Contrast: the colours above are all overridden by the OS, and
   `outline` is the only thing that survives. Keep it, drop the halo. */
@media (forced-colors: active){
  :where(a,button,[role=button],[role=tab],input,textarea,select,summary,[tabindex]):focus-visible{
    outline:3px solid Highlight; box-shadow:none;
  }
}

/* ---------------------------------------------------------------- auth card */
/* COLUMN, not row. #boot holds the card AND the credit line beneath it; as a row the
   two became side-by-side flex items and the sign-in card slid to the far left. */
.boot{min-height:100vh; display:flex; flex-direction:column;
  align-items:center; justify-content:center; padding:28px; gap:0}
.boot-card{
  background:var(--card); border:1px solid var(--line); border-radius:18px;
  padding:38px 34px 34px; max-width:432px; width:100%; text-align:center;
  box-shadow:var(--shadow)}
.boot-card .mark{display:inline-block; margin:0 auto 22px}
.boot-title{font-size:13px; letter-spacing:.2em; text-transform:uppercase;
  font-weight:700; color:var(--ink); margin:0 0 5px}
.boot-sub{color:var(--mut); font-size:13.5px; margin:0 0 24px}
.boot-msg{color:var(--mut); margin-bottom:18px; font-size:14.5px}

/* AUTH_UNKNOWN. Deliberately quiet: a page load should look like the product
   opening, not like an operation in progress. */
#bootStage{padding:14px 0 6px}
.boot-spinner{width:22px; height:22px; margin:0 auto 16px; border-radius:50%;
  border:2px solid var(--line); border-top-color:var(--amber);
  animation:pa-spin .8s linear infinite}
@keyframes pa-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){
  .boot-spinner{animation-duration:2.4s}
}

/* The product credit. Deliberately small and neutral: Petra Point is the brand,
   this is a signature. */
.boot-credit{margin:20px auto 0; text-align:center; font-size:11.5px;
  letter-spacing:.04em; color:var(--mut); opacity:.75}
.boot-err{margin-top:18px; color:var(--red); font-size:13.5px; text-align:left;
  background:color-mix(in srgb, var(--red) 8%, transparent);
  border:1px solid color-mix(in srgb, var(--red) 28%, transparent);
  border-radius:var(--radius-sm); padding:11px 13px;
  white-space:pre-wrap; word-break:break-word}
.authfield{text-align:left; margin-bottom:2px}
.authfield label{margin-top:14px}
.secretbox{
  text-align:left; background:var(--bg); border:1px solid var(--line);
  border-radius:var(--radius-sm); padding:15px 17px; margin:14px 0 8px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:15.5px; letter-spacing:.07em; word-break:break-all; line-height:2}

/* ---------------------------------------------------------------- shell */
/* ------------------------------------------------------------------ shell
   A deep NEUTRAL bar, not a slab of brand colour. Orange appears on it as the
   active page and nothing else, which is what makes it read as Petra rather than
   as "a blue SaaS app with a logo in the corner". */
.top{display:flex; align-items:center; gap:26px; padding:0 26px; height:62px;
  background:var(--shell); border-bottom:1px solid var(--shell-line);
  position:sticky; top:0; z-index:5}

/* The mark gets room and a baseline, rather than being a favicon in a navbar. */
/* The mark sits on its own white plate. The source logo is dark-on-white, so on a
   dark shell it needs the plate to be legible at all - and the plate is what makes it
   read as a deliberate identity rather than a favicon dropped into a navbar. */
.top .mark{padding:6px 9px; background:#fff; border:0; border-radius:8px;
  display:flex; align-items:center; line-height:0}
.top .mark img{height:26px; width:auto; display:block}
.top .product{color:var(--shell-mut); font-size:11px; letter-spacing:.22em;
  text-transform:uppercase; font-weight:700; padding-left:14px; margin-left:2px;
  border-left:1px solid var(--shell-line)}
.top .who{color:var(--shell-mut); font-size:13.5px}
.top-right{display:flex; align-items:center; gap:14px; margin-left:auto}

/* Navigation: quiet until it is the page you are on, then Petra orange. */
.top .tabs{gap:0; display:flex; align-items:center}
.top .tabs a{color:var(--shell-mut); background:transparent; border-radius:0;
  padding:0 2px; margin:0 16px; height:62px; display:inline-flex; align-items:center;
  box-shadow:none; font-weight:520; font-size:14px; position:relative}
.top .tabs a:hover{color:var(--shell-ink); background:transparent; box-shadow:none}
.top .tabs a.on{color:var(--shell-ink); background:transparent; box-shadow:none;
  font-weight:600}
.top .tabs a.on::after{content:''; position:absolute; left:0; right:0; bottom:0;
  height:2px; background:var(--orange); border-radius:2px 2px 0 0}

.top .ghost{border-color:var(--shell-line); color:var(--shell-ink);
  background:transparent; font-size:13.5px; padding:7px 13px}
.top .ghost:hover{background:rgba(255,255,255,.08);
  border-color:rgba(255,255,255,.24)}

.top-left{display:flex; align-items:center; gap:13px}

.brand{display:none}
.product{font-size:11.5px; letter-spacing:.2em; text-transform:uppercase;
  font-weight:700; color:var(--mut)}
.envtag{font-size:10.5px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--amber-ink); background:color-mix(in srgb, var(--amber) 16%, transparent);
  border:1px solid color-mix(in srgb, var(--amber) 34%, transparent);
  padding:3px 8px; border-radius:999px; font-weight:700}
.tabs{display:flex; gap:2px; margin-left:8px; flex:1}
.tabs a{padding:9px 14px; border-radius:var(--radius-sm); color:var(--mut);
  font-weight:560; font-size:14.5px}
.tabs a:hover{color:var(--ink); text-decoration:none; background:var(--line-2)}
.tabs a.on{color:var(--ink); background:var(--line-2); box-shadow:inset 0 -2px 0 var(--amber)}
.top-right{display:flex; align-items:center; gap:14px}
.who{color:var(--mut); font-size:14px}
main{max-width:1120px; margin:0 auto; padding:32px 26px 72px}
.foot{max-width:1120px; margin:0 auto; padding:0 26px 40px;
  color:var(--mut); font-size:12.5px; display:flex; gap:9px; flex-wrap:wrap;
  justify-content:flex-end}
.foot .credit{letter-spacing:.04em; opacity:.7}
.sep{opacity:.5}

/* ---------------------------------------------------------------- cards */
.card{background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:22px 24px; margin-bottom:16px; box-shadow:var(--shadow-sm)}
.card > h2:first-child, .card > h3:first-child{margin-top:0}
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); gap:12px;
  margin-bottom:16px}
.stat{background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:15px 17px; font-size:12.5px; color:var(--mut); letter-spacing:.02em;
  box-shadow:var(--shadow-sm)}
.stat b{display:block; font-size:23px; color:var(--ink); font-weight:650;
  letter-spacing:-.02em; margin-top:5px}

/* ------------------------------------------------- the upload, redesigned
   One file, one line of identity, one bar. A 47 KB upload does not need four
   equal boxes reporting speed, time left, elapsed and reused - that is dashboard
   weight applied to a job that finishes in nine seconds. */
.up-file{display:flex; align-items:baseline; gap:12px; margin:2px 0 18px}
.up-file .n{font-size:19px; font-weight:600; color:var(--ink);
  overflow-wrap:anywhere}
.up-file .s{font-size:13px; color:var(--mut); flex:none}
.up-pct{display:flex; align-items:baseline; justify-content:space-between;
  margin-top:11px}
.up-pct .v{font-size:26px; font-weight:640; letter-spacing:-.02em; color:var(--ink)}
.up-pct .m{font-size:12.5px; color:var(--mut)}
.up-note{margin-top:14px; font-size:13.5px; color:var(--blue);
  display:flex; align-items:center; gap:9px}
.up-note .dot{width:7px; height:7px; border-radius:50%; background:var(--blue);
  flex:none; animation:pa-breathe 2s ease-in-out infinite}

/* The journey, instead of a developer log. */
.journey{list-style:none; margin:20px 0 0; padding:0}
.journey li{display:flex; align-items:center; gap:11px; padding:7px 0;
  font-size:14px; color:var(--mut)}
.journey li .ic{width:17px; text-align:center; flex:none; font-size:13px}
.journey li.done{color:var(--ink-2)}
.journey li.done .ic{color:var(--green)}
.journey li.now{color:var(--ink); font-weight:560}
.journey li.now .ic{color:var(--blue)}
.journey li.todo .ic{color:var(--line)}

details.more{margin-top:18px}
details.more > summary{cursor:pointer; font-size:13px; color:var(--mut);
  list-style:none; display:inline-flex; align-items:center; gap:6px}
details.more > summary::-webkit-details-marker{display:none}
details.more > summary::before{content:'\203A'; display:inline-block;
  transition:transform .15s ease}
details.more[open] > summary::before{transform:rotate(90deg)}
details.more > summary:hover{color:var(--ink-2)}
details.more .body{margin-top:12px}

/* ------------------------------------------------------------ archive card */
/* The one screen an employee looks at while waiting. It must answer "did it work"
   before it answers anything else, so the state line is the largest thing on it. */
.archive-card{background:var(--card); border:1px solid var(--line);
  border-radius:var(--radius); padding:26px 26px 22px; box-shadow:var(--shadow);
  margin-bottom:18px}
.archive-file{font-size:20px; font-weight:620; letter-spacing:-.015em; margin:0;
  word-break:break-word}
.archive-size{color:var(--mut); font-size:13.5px; margin:3px 0 20px}
.state{display:flex; align-items:flex-start; gap:12px; padding:15px 17px;
  border-radius:var(--radius-sm); border:1px solid var(--line); background:var(--bg)}
.state .dot{flex:0 0 auto; width:22px; height:22px; border-radius:999px;
  display:grid; place-items:center; font-size:13px; font-weight:700; margin-top:1px;
  color:#fff}
.state > span:last-child{display:block}
.state .t{display:block; font-weight:620; font-size:15.5px; letter-spacing:-.01em}
.state .d{display:block; color:var(--mut); font-size:13.5px; margin-top:3px}
.state.done{border-color:color-mix(in srgb, var(--green) 34%, transparent);
  background:color-mix(in srgb, var(--green) 7%, transparent)}
.state.done .dot{background:var(--green)}
.state.work{border-color:color-mix(in srgb, var(--amber) 38%, transparent);
  background:color-mix(in srgb, var(--amber) 9%, transparent)}
.state.work .dot{background:var(--amber)}
.state.wait .dot{background:var(--navy-300)}
.state.bad{border-color:color-mix(in srgb, var(--red) 34%, transparent);
  background:color-mix(in srgb, var(--red) 7%, transparent)}
.state.bad .dot{background:var(--red)}
.state + .state{margin-top:9px}

/* A quiet, non-hypnotic indication that work is genuinely happening. */
.pulse{position:relative}
.pulse::after{content:""; position:absolute; inset:0; border-radius:999px;
  background:var(--amber); opacity:.45; animation:pl 2.4s ease-out infinite}
@keyframes pl{0%{transform:scale(1); opacity:.45} 70%{transform:scale(2.1); opacity:0}
  100%{opacity:0}}
@media (prefers-reduced-motion: reduce){ .pulse::after{animation:none} }

/* ---------------------------------------------------------------- pills */
.pill{display:inline-block; padding:3px 10px; border-radius:999px; font-size:12px;
  font-weight:650; letter-spacing:.01em; border:1px solid transparent}
.pill.ok{color:var(--green); background:color-mix(in srgb, var(--green) 11%, transparent);
  border-color:color-mix(in srgb, var(--green) 30%, transparent)}
/* SECURING IS BLUE, not amber. Amber next to a finished upload reads as a warning,
   and nothing is wrong - the system is simply still working. */
.pill.busy{color:var(--blue); background:color-mix(in srgb, var(--blue) 13%, transparent);
  border-color:color-mix(in srgb, var(--blue) 32%, transparent)}
.pill.warn{color:var(--orange-soft);
  background:color-mix(in srgb, var(--orange) 15%, transparent);
  border-color:color-mix(in srgb, var(--orange) 34%, transparent)}
.pill.bad{color:var(--red); background:color-mix(in srgb, var(--red) 10%, transparent);
  border-color:color-mix(in srgb, var(--red) 30%, transparent)}
.pill.idle{color:var(--mut); background:var(--line-2); border-color:var(--line)}

/* ---------------------------------------------------------------- tables */
table{width:100%; border-collapse:collapse}
th{text-align:left; font-size:11.5px; letter-spacing:.07em; text-transform:uppercase;
  color:var(--mut); font-weight:700; padding:0 12px 10px; border-bottom:1px solid var(--line)}
td{padding:13px 12px; border-bottom:1px solid var(--line-2); vertical-align:middle}
tr:last-child td{border-bottom:none}
tbody tr:hover{background:var(--line-2)}
th.right,td.right{text-align:right}

/* ---------------------------------------------------------------- progress */
.bar{height:9px; background:var(--line-2); border-radius:999px; overflow:hidden;
  position:relative; border:1px solid var(--line)}
/* PROGRESS IS BLUE. This is the clearest expression of the rule: orange is Petra,
   blue is Petra Archive doing something. A moving highlight rides the filled part
   so the bar reads as active without a spinner anywhere near it. */
.bar > div{height:100%; background:var(--blue); border-radius:999px;
  transition:width .35s ease; position:relative; overflow:hidden}
.bar > div::after{content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.28), transparent);
  transform:translateX(-100%); animation:pa-sheen 1.9s ease-in-out infinite}
@keyframes pa-sheen{60%,100%{transform:translateX(100%)}}
.bar.done > div{background:var(--green)}
.bar.done > div::after{animation:none}
@media (prefers-reduced-motion: reduce){ .bar > div::after{animation:none} }
/* UI-02. This rule used to place status text INSIDE the 9px progress track, which
   has overflow:hidden - so "0 of 1 secured" was clipped to a sliver and was
   unreadable at any zoom. Status text is now its own line beneath the track.
   The old selector is kept ONLY to neutralise any span that slips through. */
.bar > span{display:none}
.barnote{margin-top:9px; font-size:13px; color:var(--ink-2); font-weight:560;
  letter-spacing:.01em}
.meter{height:7px; background:var(--line); border-radius:999px; overflow:hidden}
.meter > div{height:100%; background:var(--accent); border-radius:999px;
  transition:width .3s ease}
.meter.warn > div{background:var(--amber)}
.meter.bad > div{background:var(--red)}

/* ---------------------------------------------------------------- notices */
.warnbox,.badbox,.okbox,.linkbox{border-radius:var(--radius-sm); padding:13px 16px;
  margin:14px 0; font-size:14px; border:1px solid; border-left-width:3px}
.warnbox{background:color-mix(in srgb, var(--amber) 8%, transparent);
  border-color:color-mix(in srgb, var(--amber) 32%, transparent); color:var(--ink)}
.badbox{background:color-mix(in srgb, var(--red) 7%, transparent);
  border-color:color-mix(in srgb, var(--red) 30%, transparent); color:var(--ink)}
.okbox{background:color-mix(in srgb, var(--green) 8%, transparent);
  border-color:color-mix(in srgb, var(--green) 30%, transparent); color:var(--ink)}
.linkbox{background:var(--bg); border-color:var(--line); word-break:break-all}
.empty{padding:40px 20px; text-align:center; color:var(--mut); font-size:14px}
.receipt{background:var(--card);
  border:1px solid color-mix(in srgb, var(--green) 32%, transparent);
  border-left:3px solid var(--green); border-radius:var(--radius); padding:22px 24px;
  margin-bottom:16px; box-shadow:var(--shadow-sm)}

/* ---------------------------------------------------------------- pickers */
.pickers{display:flex; gap:10px; flex-wrap:wrap; margin:14px 0}
.drop{border:1.5px dashed var(--line); border-radius:var(--radius); padding:34px 22px;
  text-align:center; color:var(--mut); transition:border-color .15s, background .15s}
.drop.over{border-color:var(--accent);
  background:color-mix(in srgb, var(--accent) 6%, transparent); color:var(--ink)}

/* ---------------------------------------------------------------- conditions */
/* Advanced Diagnostics only. No employee screen renders these. */
.cond{display:flex; gap:11px; align-items:flex-start; padding:9px 0;
  border-bottom:1px solid var(--line-2); font-size:13.5px}
.cond:last-child{border-bottom:none}
.cond .m{flex:0 0 auto; width:19px; height:19px; border-radius:999px; display:grid;
  place-items:center; font-size:11px; font-weight:700; background:var(--red); color:#fff}
.cond.y .m{background:var(--green)}

/* ---------------------------------------------------------------- admin */
.subtabs{display:flex; gap:2px; flex-wrap:wrap; margin:20px 0 18px;
  border-bottom:1px solid var(--line)}
.subtabs a, .subtabs button{background:transparent; border:none;
  border-bottom:2px solid transparent; text-decoration:none;
  border-radius:0; color:var(--mut); font-weight:600; padding:10px 14px; font-size:14px}
.subtabs a:hover, .subtabs button:hover{color:var(--ink); text-decoration:none}
.subtabs a.on, .subtabs button.on{color:var(--ink);
  border-bottom-color:var(--amber)}
.rowform{display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end; margin:10px 0 4px}
.rowform .authfield{margin:0; flex:1 1 190px}
.rowform label{margin-top:0}
.rowform button{margin-bottom:1px}

/* ---------------------------------------------------------------- modal */
.modal{position:fixed; inset:0; background:rgba(11,15,36,.52); display:flex;
  align-items:center; justify-content:center; padding:24px; z-index:50}
.modal-card{background:var(--card); border:1px solid var(--line); border-radius:16px;
  padding:26px 28px; max-width:520px; width:100%; max-height:86vh; overflow:auto;
  box-shadow:0 18px 60px rgba(11,15,36,.28)}
.modal-card h2{margin:0 0 10px; font-size:19px; text-transform:none;
  letter-spacing:-.012em; color:var(--ink)}
.modal-actions{display:flex; gap:10px; justify-content:flex-end; margin-top:22px}

/* Long names must not decide the layout. A survey deliverable is routinely called
   something like "Topographic Survey (rev 3) - Marina Plot 14.dwg", and an Arabic
   name can be longer still. */
td .name, .name{word-break:break-word; overflow-wrap:anywhere}

@media (max-width:780px){
  /* THE HEADER HAD A FIXED HEIGHT AND WAS ALLOWED TO WRAP.
     `.top{height:62px}` is right on a desktop, where the strip is one row. Below this
     width `flex-wrap:wrap` puts the navigation on its own line - but 62px was never
     lifted, so the header's BOX stayed 62px tall while its CONTENT grew to roughly
     250px, and everything past the first row was drawn on top of the page beneath it.
     On a 390px screen the word "Admin" sat directly over the navigation. The layout
     reported no horizontal overflow throughout, which is why a scroll-width contract
     alone is not enough and the sweep now checks for overlap too. */
  .top{flex-wrap:wrap; gap:12px; padding:12px 16px; height:auto; min-height:62px}

  /* AND THE NAVIGATION WRAPPED INSTEAD OF SCROLLING.
     `overflow-x:auto` can only scroll something that refuses to wrap; a flex row that
     is allowed to wrap simply gets taller and never overflows. Saying so explicitly is
     what turns the strip into the one-line scroller it was always meant to be. */
  .tabs{order:3; width:100%; overflow-x:auto; -webkit-overflow-scrolling:touch;
    flex-wrap:nowrap}
  .tabs a{white-space:nowrap; flex:0 0 auto}
  .top .tabs a{margin:0 14px 0 0}
  main{padding:22px 16px 60px}
  h1{font-size:22px}
  .card{padding:18px 16px}
  .foot{padding:0 16px 32px; justify-content:center}
  .boot{padding:18px}
  .boot-card{padding:30px 22px 26px}

  /* TABLES GET AN INTENTIONAL STRATEGY rather than being left to push the page
     sideways. They scroll inside their own card, so the PAGE never scrolls
     horizontally - which is the thing that makes a site feel broken on a phone. */
  .card{overflow-x:auto}
  table{min-width:540px}

  /* Rows of controls stack instead of squeezing. */
  .row.spread{flex-direction:column; align-items:stretch; gap:12px}
  .row.spread .primary, .row.spread .ghost{width:100%}
}

@media (max-width:420px){
  .top .product{display:none}
  h1{font-size:20px}
}


/* ---------------------------------------------------- background protection
   A calm, finite-looking indicator. NOT an endless spinner: the upload is finished
   and a spinner says "still working, keep watching", which is exactly the impression
   the copy is trying to remove. */
.securing{display:flex; align-items:center; gap:10px; margin-bottom:12px}
.securing .dot{width:8px; height:8px; border-radius:50%; background:var(--amber);
  flex:none; animation:pa-breathe 2.2s ease-in-out infinite}
@keyframes pa-breathe{0%,100%{opacity:.35}50%{opacity:1}}
@media (prefers-reduced-motion: reduce){ .securing .dot{animation:none; opacity:.85} }


/* ---------------------------------------------------------------- page head
   Title, one quiet line, and the page's primary action - on one row. Premium UI
   carries hierarchy in type and space, not in a box around every group. */
.pagehead{display:flex; align-items:flex-start; justify-content:space-between;
  gap:24px; margin:0 0 26px}
.pagehead h1{margin:0 0 5px}
.pagehead .sub{margin:0}
.pagehead .primary{flex:none}

/* ------------------------------------------------------------- empty states
   Restrained: a statement, a sentence, and the one action that resolves it.
   No illustration, no card, no exclamation marks. */
.empty-state{text-align:center; padding:64px 24px 70px;
  border:1px dashed var(--line); border-radius:var(--radius)}
/* The global h2 is an uppercase tracked section label; an empty state is a sentence
   to a person, not a section heading, so it opts out. */
.empty-state h2{margin:0 0 7px; font-size:17px; color:var(--ink); font-weight:600;
  text-transform:none; letter-spacing:-.01em}
.empty-state p{margin:0 0 20px; color:var(--mut); font-size:14px}

/* -------------------------------------------------------------- table polish
   Fewer rules, more air, and the name is allowed to dominate. */
th{padding:0 14px 12px}
td{padding:15px 14px}
tbody tr:hover{background:var(--line-2)}
td .name{font-weight:560; color:var(--ink)}
td.num, th.num{text-align:right; font-variant-numeric:tabular-nums}
.rowact{color:var(--mut); font-size:13px; white-space:nowrap}
tr:hover .rowact{color:var(--orange)}
thead th{position:sticky; top:62px; background:var(--card); z-index:1}


/* -------------------------------------------------------- audit / security
   The detail row sits under its event and is closed by default, so the table
   reads as a list of sentences rather than a wall of payloads. */
tr.detrow td{padding:0 14px 12px; border-bottom:1px solid var(--line-2)}
tr.detrow:hover{background:transparent}
pre.raw{margin:0; padding:12px 14px; background:var(--line-2);
  border:1px solid var(--line); border-radius:var(--radius-sm);
  font-size:12px; line-height:1.55; color:var(--ink-2);
  max-height:260px; overflow:auto; white-space:pre-wrap; word-break:break-word}

/* A form row that is not wrapped in a card. */
.rowform.bare{background:transparent; border:0; padding:0; margin-bottom:20px}


/* ------------------------------------------------------- admin sub-navigation
   Business administration on the left, system administration set apart on the
   right. Grouping by SPACE rather than by a hidden menu: every control stays one
   click away, which is the whole point. */
.subtabs{display:flex; align-items:center; gap:28px; flex-wrap:wrap}
.subtabs .grp{display:flex; align-items:center; gap:4px; flex-wrap:wrap}
.subtabs .grp.sys{padding-left:26px; border-left:1px solid var(--line); gap:2px}
.subtabs .grp.sys a, .subtabs .grp.sys button{font-size:13px; color:var(--mut)}
.subtabs .grp.sys a:hover, .subtabs .grp.sys button:hover{color:var(--ink-2)}
.subtabs .grp.sys a.on, .subtabs .grp.sys button.on{color:var(--ink)}
.subtabs .glab{font-size:10.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--mut); opacity:.7; margin-right:8px; font-weight:700}
@media (max-width:900px){
  .subtabs{gap:12px}
  .subtabs .grp.sys{padding-left:0; border-left:0; width:100%}
}

/* ON A PHONE THE TWO GROUPS BECAME FOUR ROWS.
   The two-row shape above is deliberate - business administration, then system
   administration on its own line - but each GROUP was also allowed to wrap, so at
   390px "Overview Employees Archives" broke across two lines and "Uploads Client
   Links" across another, and the sub-navigation took a third of the screen before any
   content appeared.

   The design keeps its two rows. Each row simply becomes one scrollable line, which is
   the same treatment the main navigation gets at this width. Declared here rather than
   with the other phone rules because `.subtabs{flex-wrap:wrap}` is defined further
   down the file and would otherwise win. */
@media (max-width:780px){
  .subtabs{flex-wrap:wrap; gap:10px; margin:14px 0 16px}
  .subtabs .grp{flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch;
    width:100%; gap:6px; padding-bottom:2px}
  .subtabs .grp a, .subtabs .grp button{white-space:nowrap; flex:0 0 auto}
  .subtabs .glab{flex:0 0 auto}

  /* NO SCROLLBAR ON A NAVIGATION STRIP. A phone draws an overlay scrollbar that
     disappears on its own; a desktop browser at this width draws the classic one, and
     two grey troughs with arrow buttons across the top of the console look like a
     rendering fault rather than a design. The affordance is kept by the content itself:
     the strip is clipped mid-item, which is what tells a person it continues.
     Deliberately scoped to the two navigation strips - a table inside a card keeps its
     scrollbar, where the affordance is the only thing that says the columns continue. */
  .tabs::-webkit-scrollbar, .subtabs .grp::-webkit-scrollbar{display:none}
  .tabs, .subtabs .grp{scrollbar-width:none; -ms-overflow-style:none}
}

#bootMsg:empty{display:none}

/* =========================================================================
   ADMIN LAYOUT - width, and what to do when there is not enough of it
   =========================================================================

   THE DEFECT THIS FIXES, measured rather than guessed. At 1366x768 @100% the
   Admin Employees page does NOT overflow the document - scrollWidth 1333 against
   a 1348 viewport, zero offending elements. It is SQUEEZED, not clipped:

     * `main` caps every page at 1120px, so a 1366 viewport leaves 246px unused
       and a 1920 one leaves 800px unused;
     * the Employees table gets ~1068px for six columns, the last of which holds
       up to six action buttons;
     * `.actions{flex-wrap:wrap}` then wraps those buttons over two and three
       rows, the header labels wrap too, and rows grow past 100px tall, so the
       actions of later rows fall below the fold.

   Zooming the browser out hands `main` more CSS pixels, the buttons stop
   wrapping, and it looks fixed - which is exactly the symptom reported. The
   answer is therefore not `overflow-x:auto`; it is to use the width the screen
   already has, and to stop pretending six buttons per row is a column. */

main.wide{max-width:1560px}
.foot.wide{max-width:1560px}

/* A flex child refuses to shrink below its content unless told it may. Without
   this the header's tab strip can push the shell wider than the viewport on a
   narrow laptop - the classic min-width:auto trap. */
.top{min-width:0}
.top .tabs{min-width:0; flex:1 1 auto; overflow:hidden}
main{min-width:0}
.card{min-width:0}

/* ---------------------------------------------------- admin data tables */
/* One table class, three column priorities. `pri-1` always shows, `pri-2` goes
   first, `pri-3` goes next. Nothing is lost - everything hidden here is also on
   the row's own detail line, which is why hiding it is honest rather than a
   trick to make a screenshot pass. */
.tbl{width:100%; table-layout:auto}
.tbl th, .tbl td{vertical-align:top}
.tbl .grow{width:100%}                    /* the name column absorbs the slack */
.tbl .tight{white-space:nowrap; width:1%}  /* pills and dates never wrap */
.tbl td.tight, .tbl th.tight{padding-right:18px}

/* ------------------------------------------------------------ row actions */
/* Two actions inline, the rest one click away. Six ghost buttons in a cell is
   not a column, it is a paragraph of buttons - and it was the direct cause of
   the 100px rows. */
.rowacts{display:flex; align-items:flex-start; justify-content:flex-end; gap:6px;
  white-space:nowrap}
.rowmenu{position:relative; display:inline-block}
.rowmenu > summary{list-style:none; cursor:pointer; padding:5px 10px; font-size:13px;
  border:1px solid var(--line); border-radius:var(--radius-sm); color:var(--mut);
  background:transparent; user-select:none}
.rowmenu > summary::-webkit-details-marker{display:none}
.rowmenu > summary:hover{color:var(--ink); border-color:var(--line-2)}
.rowmenu[open] > summary{color:var(--ink); border-color:var(--amber)}
.rowmenu .menu{position:absolute; right:0; top:calc(100% + 6px); z-index:40;
  min-width:212px; padding:6px; background:var(--card);
  border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:0 18px 40px rgba(0,0,0,.34); display:flex; flex-direction:column;
  gap:2px; white-space:nowrap}
.rowmenu .menu button{width:100%; text-align:left; background:transparent;
  border:0; padding:8px 10px; border-radius:var(--radius-sm); font-size:13.5px;
  color:var(--ink-2)}
.rowmenu .menu button:hover{background:var(--line-2); color:var(--ink)}
.rowmenu .menu .sep{height:1px; background:var(--line); margin:4px 2px; opacity:1}
.rowmenu .menu button.danger{color:var(--red)}
.rowmenu .menu button.danger:hover{background:color-mix(in srgb,var(--red) 14%,transparent);
  color:var(--red)}
.rowmenu .menu button[disabled]{opacity:.45; cursor:default}
.rowmenu .menu button[disabled]:hover{background:transparent; color:var(--ink-2)}
.rowmenu .why{font-size:11.5px; color:var(--mut); padding:2px 10px 6px;
  white-space:normal; max-width:230px; line-height:1.45}

/* ----------------------------------------------------------- narrowing */
@media (max-width:1180px){
  .tbl .pri-3{display:none}
}
@media (max-width:980px){
  .tbl .pri-2{display:none}
}
/* Below this a six-column table is a worse answer than a stacked row. The card
   mode keeps every field and every action; it stops pretending to be a grid. */
@media (max-width:860px){
  .tbl, .tbl tbody, .tbl tr, .tbl td{display:block; width:auto}
  .tbl thead{display:none}
  .tbl tr{border:1px solid var(--line); border-radius:var(--radius);
    padding:14px 16px; margin-bottom:12px}
  .tbl td{border:0; padding:4px 0}
  .tbl td.pri-2, .tbl td.pri-3{display:block}
  .tbl td::before{content:attr(data-label); display:block; font-size:11px;
    letter-spacing:.07em; text-transform:uppercase; color:var(--mut);
    margin-bottom:3px}
  .tbl td:first-child::before{content:none}
  .rowacts{justify-content:flex-start; flex-wrap:wrap; white-space:normal;
    margin-top:10px}
  .rowmenu .menu{right:auto; left:0}
}

/* A row menu on the last visible row opened downward into the fold and was clipped.
   It flips when there is not room below - decided from the live rectangle rather than
   from a media query, because "room below" depends on scroll position, not width. */
.rowmenu.up .menu{top:auto; bottom:calc(100% + 6px)}

/* AND ON A PHONE IT OPENED OFF THE SIDE OF THE SCREEN.
   `left:0` anchors the 198px menu to the LEFT edge of its trigger, and the trigger
   sits wherever the row put it - measured at x=136 on a 320px screen and x=280 on a
   430px one, so the menu ran 14px and 48px past the right edge and its actions could
   not be reached at all. `right:0` is no better: it just fails at the other end.

   A menu cannot be positioned correctly from the trigger alone without knowing where
   the trigger is, and CSS anchor positioning is not something this product can rely on
   yet. So below 560px the menu stops being a dropdown and becomes what a phone
   actually wants: a sheet pinned to the bottom of the VIEWPORT, always fully on
   screen, whatever the trigger did. It scrolls if the list is long. */
@media (max-width:560px){
  .rowmenu[open] .menu{
    position:fixed; left:12px; right:12px; top:auto; bottom:12px;
    width:auto; min-width:0; max-width:none; max-height:62vh; overflow-y:auto;
    box-shadow:0 -6px 32px rgba(0,0,0,.34)}
  .rowmenu[open] .menu button{padding:12px 12px; font-size:14.5px}
  .rowmenu.up .menu{bottom:12px}
}

/* =========================================================================
   FOOTER, AND THE SHAPE OF A SHORT PAGE
   ========================================================================= */
/* The credit floated wherever the content stopped - halfway up an empty Settings
   page, which reads as a layout accident rather than a signature. The shell becomes
   a column, `main` takes the slack, and the footer sits on the bottom of the
   viewport when the page is short and after the content when it is long. */
#shell{display:flex; flex-direction:column; min-height:100vh}
#shell > main{flex:1 0 auto}
#shell > .foot{flex:0 0 auto; margin-top:28px}

/* 7A - one width rule per audience, stated once.
   Employee reading column stays comfortable; the admin console uses the screen. */
main{max-width:1240px}
.foot{max-width:1240px}

/* =========================================================================
   POLICY SWITCHES  (Part 11)
   =========================================================================
   A boolean policy rendered as a 220px Yes/No select is both oversized and mute:
   the screen said "Administrators must use an authenticator", showed "No", and
   then advised "Leave this on." Three things, disagreeing. A switch states the
   effective value, and the sentence beneath it is derived from that value. */
.policy{display:flex; gap:16px; align-items:flex-start; padding:16px 0;
  border-bottom:1px solid var(--line-2)}
.policy:last-of-type{border-bottom:0}
.policy-text b{display:block; font-size:14.5px; color:var(--ink); font-weight:620}
.policy .state{font-size:12.5px; color:var(--mut); margin-top:3px}
.policy .state .v{display:inline; font-weight:700; color:var(--mut)}
.policy.on .state .v{color:var(--green)}
.policy .hint{margin-top:6px}
.switch{position:relative; display:inline-block; flex:0 0 auto; margin-top:2px}
.switch input{position:absolute; opacity:0; width:44px; height:26px; margin:0;
  cursor:pointer}
.switch .track{display:block; width:44px; height:26px; border-radius:999px;
  background:var(--line-2); border:1px solid var(--line); transition:background .15s}
.switch .knob{display:block; width:20px; height:20px; border-radius:50%;
  background:var(--mut); margin:2px; transition:transform .15s, background .15s}
.policy.on .switch .track{background:color-mix(in srgb,var(--green) 34%,transparent);
  border-color:var(--green)}
.policy.on .switch .knob{transform:translateX(18px); background:var(--green)}
.switch input:focus-visible + .track{outline:2px solid var(--focus);
  outline-offset:2px}
@media (prefers-reduced-motion: reduce){
  .switch .track, .switch .knob{transition:none}
}

/* =========================================================================
   RESPONSIVE ROOT CAUSE  (measured, CDP, true viewports)
   =========================================================================

   At 390x844 the document was 606px wide against a 390px viewport. Two causes,
   and the first one was mine:

   1. `#shell{display:flex; flex-direction:column}` was added to pin the footer.
      A COLUMN flex container with `width:auto` is shrink-to-fit: it sizes to the
      MAX-CONTENT of its items. `main` therefore stretched to the widest thing
      inside it instead of to the viewport, and the whole page grew with it.
      A flex container used for vertical layout must still be told it is full
      width.

   2. `@media (max-width:780px){ table{min-width:540px} }` predates `.tbl`. Once
      `.tbl` switches to stacked cards it is `display:block`, but the 540px floor
      still applied - so a "responsive" table carried a 540px minimum on a 320px
      phone. The floor belongs to the tables that still scroll inside their card,
      not to the one that stopped being a table. */

#shell{width:100%; max-width:100%}
#shell > main, #shell > .foot{width:100%; max-width:100%}
main.wide{max-width:1560px}

@media (max-width:860px){
  /* `.tbl` is not a table any more here; it must not keep a table's floor. */
  table.tbl{min-width:0}
  .card:has(> table.tbl), .card:has(table.tbl){overflow-x:visible}
}

/* 3. AND THE FLOOR ONLY EVER WORKED FOR TABLES THAT HAD A CARD AROUND THEM.
      `.card{overflow-x:auto}` plus `table{min-width:540px}` is a sound strategy -
      the table scrolls, the page does not - but it silently depends on every table
      being wrapped, and nine of them are not. The audit log is emitted straight
      into `main`, so at 320px it carried its 540px floor with nothing to contain
      it and pushed the document to 556px.

      Rather than add a wrapper at nine call sites and trust the tenth to be
      remembered, the table becomes its own scroll container. `display:block` makes
      it a block box that can scroll; the row groups go back to `table` so the
      columns still line up, and the floor moves onto them so columns keep their
      width INSIDE the scroller. A table that already has a card simply scrolls at
      the inner level instead of the outer one, which looks identical. */
@media (max-width:780px){
  table:not(.tbl){display:block; overflow-x:auto; min-width:0;
                  -webkit-overflow-scrolling:touch}
  table:not(.tbl) > thead, table:not(.tbl) > tbody, table:not(.tbl) > tfoot{
    display:table; width:100%; min-width:540px}
}

/* Nothing in the product may set its own width in a way the viewport cannot
   contain. Stated once, at the top, rather than chased element by element. */
img, svg, video, canvas, table, pre, input, select, textarea, button{max-width:100%}
input, select, textarea{box-sizing:border-box}

/* =========================================================================
   A BUTTON THAT IS WAITING

   A disabled button is not feedback. Sign-in went grey and stayed grey while
   Argon2id did its 130 ms and the request went to an origin that was measured
   stalling for over five seconds on about 40% of calls - so a person could look
   at an unchanged screen for six seconds and reasonably conclude it was broken.

   The label now says what is happening. This mark says it is still happening.
   It is a quiet pulse rather than a spinner, for the same reason the upload
   indicator is: a spinner implies an unknown wait, and these waits are short.
   ========================================================================= */
/* `opacity:1` because the button IS disabled while it waits, and the 45% fade that
   normally signals "you cannot press this" would here read as "this is broken". The
   colour is deliberately left alone: a working `.primary` keeps its dark ink on amber,
   and the mark inherits it through `currentColor`. */
button.working{position:relative; cursor:default; opacity:1}
button.working::after{content:""; display:inline-block; width:6px; height:6px;
  border-radius:50%; background:currentColor; margin-left:8px;
  vertical-align:middle; opacity:.75;
  animation:pa-breathe 1.1s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){
  button.working::after{animation:none; opacity:.8}
}

/* AN IPv6 ADDRESS DOES NOT WRAP, AND PRODUCTION HAS THEM.
   Admin > Sessions renders `clientIp` into a `td.mono`. Every local fixture used a
   short IPv4 literal, so the local sweep passed at 320px; the first real measurement
   against production - where a client address is
   `2001:8f8:1577:184f:1147:7fbf:1531:139e`, thirty-nine characters with no break
   opportunity - pushed the document to 331px against a 320px viewport.

   Monospace cells are exactly where opaque machine values land: addresses, ids,
   digests. They are allowed to break anywhere, because a wrapped address is readable
   and a horizontally scrolling page is not. Prose is untouched - this is scoped to
   cells that opted into `.mono`. */
td.mono, .tbl td.mono, td .mono{overflow-wrap:anywhere; word-break:break-word}

/* The open hint and the row menu share the last cell in My Archive. Without this the
   hint and the menu sit on separate lines and the row doubles in height. */
.rowacts .open-hint{color:var(--mut); font-size:13px; white-space:nowrap;
  align-self:center}
