/* ============================================================================
   The dashboard, dressed as a job docket.

   This is used standing up, one-handed, outdoors, between jobs. Every choice
   below answers to that: type large enough to read in sunlight, tap targets a
   glove can hit, square corners and ruled panels that read as a work document
   rather than a web app, and colour used only where it carries meaning.

   Colour is a language here, not decoration. Read it once and the screens
   explain themselves:
     accent (green)  a person, a safe action, a thing that went out
     bad    (red)    destructive, refused, never reached them
     warn   (amber)  unfinished, unknown, in flight
     ink-2/3         the system talking about itself, never a customer

   Every token is declared on bare :root. Nothing has its only definition
   inside a media query - that is how a page ends up unreadable in one theme.
   ========================================================================= */

:root{
  /* --- light, the default and the one that has to win in sunlight --- */
  --paper:#ECEEE8;        /* the desk */
  --card:#FFFFFF;         /* the docket */
  --sunk:#E2E5DC;         /* recessed: drafts, empty states, things not real yet */
  --ink:#161A12;          /* 17.6:1 on card, 15.1:1 on paper */
  --ink-2:#4B5447;        /*  7.9:1 on card,  6.8:1 on paper */
  --ink-3:#5D6654;        /*  6.0:1 on card,  4.7:1 on sunk  */
  --line:#D2D7C9;         /* hairline separators */
  --rule:#828C72;         /* structural rules, 3.5:1 on card */
  --accent:#1D5A32;       /*  8.2:1 on card */
  --on-accent:#FFFFFF;    /*  8.2:1 on accent */
  --bad:#9C2418;          /*  7.8:1 on card */
  --warn:#7E4708;         /*  7.5:1 on card */
  --focus:#1D5A32;

  --tap:48px;
  --top-h:54px;
  --r:3px;                /* squared, not rounded */
  --pad:14px;
  --maxw:760px;
  --font:"Archivo","Segoe UI",Roboto,-apple-system,BlinkMacSystemFont,
         "Helvetica Neue",Arial,sans-serif;
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#0F1210;
    --card:#191D18;
    --sunk:#131714;
    --ink:#EAEEE4;        /* 14.5:1 on card */
    --ink-2:#AEB7A8;      /*  8.2:1 on card */
    --ink-3:#8D9787;      /*  5.6:1 on card */
    --line:#2E342C;
    --rule:#697362;       /*  3.4:1 on card */
    --accent:#7FCB90;     /*  8.8:1 on card */
    --on-accent:#0F1210;  /*  9.7:1 on accent */
    --bad:#FF8E7D;        /*  7.7:1 on card */
    --warn:#E8A63F;       /*  8.1:1 on card */
    --focus:#7FCB90;
  }
}

:root[data-theme="dark"]{
  --paper:#0F1210;
  --card:#191D18;
  --sunk:#131714;
  --ink:#EAEEE4;
  --ink-2:#AEB7A8;
  --ink-3:#8D9787;
  --line:#2E342C;
  --rule:#697362;
  --accent:#7FCB90;
  --on-accent:#0F1210;
  --bad:#FF8E7D;
  --warn:#E8A63F;
  --focus:#7FCB90;
}

*,*::before,*::after{box-sizing:border-box}

html{-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--paper);          /* explicit, from a token, always */
  color:var(--ink);
  font:400 17px/1.45 var(--font);
  overflow-wrap:break-word;
  padding-bottom:calc(var(--tap) + 30px + env(safe-area-inset-bottom));
  -webkit-tap-highlight-color:transparent;
}

::selection{background:var(--accent);color:var(--on-accent)}

/* --- focus: one visible, unmissable treatment everywhere ------------------ */
:focus{outline:none}
:focus-visible{
  outline:3px solid var(--focus);
  outline-offset:2px;
  border-radius:2px;
}
/* Form fields ring on plain :focus, not only :focus-visible. Chrome's date and
   time pickers move focus between their own inner segments, and while they do
   :focus-visible stops matching - which left two fields on the new-enquiry
   form with no ring at all. Measured, not assumed. */
input:focus,textarea:focus,select:focus,
input:focus-within,textarea:focus-within,select:focus-within{
  outline:3px solid var(--focus);outline-offset:2px;border-color:var(--ink);
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    transition-duration:.01ms !important;
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    scroll-behavior:auto !important;
  }
}

/* ============================ chrome ===================================== */

header.top{
  position:sticky;top:0;z-index:20;
  min-height:var(--top-h);
  background:var(--card);
  border-bottom:2px solid var(--rule);
  padding:0 var(--pad);
  display:flex;align-items:center;gap:10px;
}
header.top h1{
  margin:0;font-size:19px;font-weight:700;letter-spacing:-.012em;
  line-height:1.15;min-width:0;overflow-wrap:anywhere;
}
header.top .back{
  display:inline-flex;align-items:center;justify-content:center;
  width:var(--tap);height:var(--tap);margin-left:calc(var(--pad) * -1);
  color:var(--ink);text-decoration:none;flex:0 0 auto;
}
header.top .back::before{
  content:"";width:11px;height:11px;
  border-left:2.5px solid currentColor;border-bottom:2.5px solid currentColor;
  transform:rotate(45deg);margin-left:4px;
}
header.top .n{
  margin-left:auto;flex:0 0 auto;
  font-size:15px;font-weight:600;color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}

/* --- which face this session is wearing ------------------------------------
   In the STICKY header, so it is on screen at the moment of the tap and not
   only at the top of the page. It borrows the colour language already used by
   `.oscar-bar__tag` rather than inventing a third: solid ink is level 1 - him,
   his controls, the surface the client cannot see - and sunk-and-dashed is the
   client's own face, the same grammar every L1-only block on her card uses.

   Nothing renders here for the client. A band explaining a mode she does not
   have is chrome, and this app has none. */
header.top .mode{
  margin-left:auto;flex:0 0 auto;
  padding:4px 8px;font-size:11.5px;font-weight:700;line-height:1.25;
  letter-spacing:.09em;text-transform:uppercase;white-space:nowrap;
}
header.top .mode + .n{margin-left:8px}
.mode--l1{background:var(--ink);color:var(--paper)}
.mode--dropin{
  background:var(--sunk);color:var(--ink-2);
  border:1px dashed var(--rule);padding:3px 7px;
}
/* The rule under the header thickens into ink at level 1 - the same edge the
   L1 blocks on a card carry, so the whole screen reads as his and not hers. */
header.top--l1{border-bottom-color:var(--ink)}

main{padding:14px 12px 28px;max-width:var(--maxw);margin:0 auto}

nav.tabs{
  position:fixed;left:0;right:0;bottom:0;z-index:30;
  background:var(--card);
  border-top:2px solid var(--rule);
  display:flex;
  padding-bottom:env(safe-area-inset-bottom);
}
nav.tabs a{
  flex:1 1 0;min-width:0;min-height:var(--tap);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:3px;padding:6px 2px;
  color:var(--ink-2);text-decoration:none;
  font-size:12px;font-weight:600;letter-spacing:.01em;
}
nav.tabs a svg{width:22px;height:22px;display:block}
nav.tabs a.on{color:var(--accent)}
nav.tabs a.on::before{
  content:"";position:absolute;margin-top:-8px;
  width:26px;height:3px;background:var(--accent);
}
nav.tabs a:active{background:var(--sunk)}

/* ============================ notices ==================================== */

.notice{
  background:var(--card);
  border:1px solid var(--line);
  border-left:5px solid var(--accent);
  border-radius:var(--r);
  padding:12px 14px;margin:0 0 14px;
  font-size:16px;line-height:1.4;color:var(--ink);
  display:flex;gap:10px;align-items:flex-start;
}
.notice__mark{
  flex:0 0 auto;width:20px;height:20px;margin-top:1px;color:var(--accent);
}

/* ============================ panels ===================================== */

.panel{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--r);
  padding:var(--pad);
  margin:0 0 12px;
}
.panel--sunk{background:var(--sunk);border-style:dashed;border-color:var(--rule)}

.section{margin:26px 0 10px}
.section h2{
  margin:0;font-size:13px;font-weight:700;text-transform:uppercase;
  letter-spacing:.1em;color:var(--ink-2);
  padding-bottom:6px;border-bottom:2px solid var(--rule);
}
.section p{margin:6px 0 0;font-size:15px;color:var(--ink-2)}

.hint{
  font-size:15px;line-height:1.4;color:var(--ink-3);margin:6px 0 0;
}
.hint--warn{color:var(--warn)}
.hint--bad{color:var(--bad)}

.empty{
  background:var(--sunk);
  border:1px dashed var(--rule);
  border-radius:var(--r);
  padding:34px 22px;text-align:center;color:var(--ink-2);
}
.empty strong{display:block;font-size:19px;color:var(--ink);margin-bottom:6px}
.empty p{margin:0;font-size:16px;line-height:1.45;color:var(--ink)}

/* ============================ stamps ===================================== */
/* A stamp is a boxed label, like an ink stamp on a docket. Never a pill. */

.stamp{
  display:inline-block;
  font-size:11.5px;font-weight:700;line-height:1.35;
  text-transform:uppercase;letter-spacing:.09em;
  padding:2px 7px;border:1.5px solid currentColor;border-radius:2px;
  color:var(--ink-2);
  /* A stamp must never be the thing that widens the page. Two of them in one
     row at 320px used to push the document to 404px wide. */
  max-width:100%;min-width:0;overflow-wrap:anywhere;
}
.stamp--urgent{color:var(--bad)}
.stamp--new{color:var(--accent)}
.stamp--calm{color:var(--ink-2)}
.stamp--warn{color:var(--warn)}
.stamp--solid{background:var(--bad);border-color:var(--bad);color:var(--card)}

/* ============================ buttons ==================================== */
/* Three tiers, and the difference is deliberate:
   .btn--go      irreversible. Filled, heavy, says what it will do.
   .btn--danger  destructive. Outlined in red, kept away from everything else.
   .btn / .btn--quiet  safe. Plain outlines, no weight, no alarm. */

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font:600 17px/1.2 var(--font);
  min-height:var(--tap);padding:12px 18px;
  border:2px solid var(--rule);border-radius:var(--r);
  background:var(--card);color:var(--ink);
  text-decoration:none;cursor:pointer;text-align:center;
  width:100%;
}
.btn:active{background:var(--sunk)}
.btn[disabled],.btn:disabled{
  opacity:1;color:var(--ink);border-color:var(--rule);border-style:dashed;
  background:var(--sunk);cursor:not-allowed;
}

.btn--go{
  background:var(--accent);border-color:var(--accent);color:var(--on-accent);
  font-weight:700;
}
.btn--go:active{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.btn--go[disabled]{
  background:var(--sunk);border-color:var(--rule);border-style:dashed;
  color:var(--ink);
}

.btn--primary{
  background:var(--card);border-color:var(--accent);color:var(--accent);
  font-weight:700;
}

.btn--danger{
  background:var(--card);border-color:var(--bad);color:var(--bad);
}
.btn--danger:active{background:var(--bad);color:var(--card)}

.btn--quiet{border-color:var(--line);color:var(--ink-2);font-weight:600}

.btn-row{display:flex;gap:8px;flex-wrap:wrap}
.btn-row .btn{width:auto;flex:1 1 60px;min-width:0;padding:12px 8px}

.danger-zone{
  margin-top:32px;padding-top:16px;border-top:2px solid var(--line);
}

/* ============================ forms ====================================== */

.field{margin:0 0 16px}
.field > label,
label.field__label{
  display:block;font-size:15px;font-weight:600;color:var(--ink);
  margin:0 0 5px;
}
.field .req{color:var(--bad);font-weight:700}

/* Every text-ish control, listed by exclusion rather than by name, so a field
   type added later cannot quietly render 24px tall on a phone - which is what
   the date and time pickers did. */
input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=file]),
textarea,select{
  width:100%;
  font:400 17px/1.35 var(--font);
  color:var(--ink);background:var(--card);
  border:2px solid var(--rule);border-radius:var(--r);
  padding:12px 12px;min-height:var(--tap);
}
textarea{min-height:96px;resize:vertical}
select{
  appearance:none;-webkit-appearance:none;
  padding-right:38px;
  background-image:linear-gradient(45deg,transparent 49%,var(--ink-2) 50%),
                   linear-gradient(-45deg,transparent 49%,var(--ink-2) 50%);
  background-size:8px 8px,8px 8px;
  background-position:calc(100% - 20px) 22px,calc(100% - 13px) 22px;
  background-repeat:no-repeat;
}
input::placeholder,textarea::placeholder{color:var(--ink-3);opacity:1}

input:user-invalid,textarea:user-invalid,
input[aria-invalid="true"],textarea[aria-invalid="true"]{
  border-color:var(--bad);
}
input:user-invalid ~ .hint,textarea:user-invalid ~ .hint{color:var(--bad)}

.check{
  display:flex;align-items:center;gap:12px;
  min-height:var(--tap);padding:8px 12px;margin:0 0 16px;
  border:2px solid var(--rule);border-radius:var(--r);background:var(--card);
  font-size:16px;font-weight:500;cursor:pointer;
}
.check input{width:24px;height:24px;min-height:0;flex:0 0 auto;accent-color:var(--accent)}

/* ============================ list rows ================================== */
/* A row is a tappable surface, not a link in a table. No underline, no blue,
   a chevron so the thumb knows, and a pressed state so it answers. */

.rows{border-top:1px solid var(--line)}
.row{
  display:flex;align-items:center;gap:12px;
  min-height:64px;padding:12px 12px 12px 14px;
  background:var(--card);border-bottom:1px solid var(--line);
  color:var(--ink);text-decoration:none;
}
.row:active{background:var(--sunk)}
.row__main{flex:1 1 auto;min-width:0}
.row__name{font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.25}
.row__sub{
  margin-top:3px;font-size:15px;color:var(--ink-2);
  display:flex;flex-wrap:wrap;gap:4px 12px;
  font-variant-numeric:tabular-nums;
}
.row__go{
  flex:0 0 auto;width:10px;height:10px;
  border-right:2.5px solid var(--ink-3);border-top:2.5px solid var(--ink-3);
  transform:rotate(45deg);
}

/* ============================ the queue ================================== */

.queue-head{
  background:var(--card);border:1px solid var(--line);
  border-top:4px solid var(--ink);border-radius:var(--r);
  padding:14px var(--pad) 12px;margin-bottom:16px;
}
.queue-head__n{
  font-size:38px;font-weight:700;line-height:1;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
}
.queue-head__n small{
  font-size:16px;font-weight:600;letter-spacing:0;color:var(--ink-2);
  margin-left:8px;
}
.jump{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.jump a{
  display:inline-flex;align-items:center;gap:7px;
  min-height:48px;padding:8px 12px;width:100%;
  border:1.5px solid var(--line);border-radius:var(--r);
  background:var(--paper);color:var(--ink);text-decoration:none;
  font-size:14.5px;font-weight:600;
}
.jump a:active{background:var(--sunk)}
.jump b{font-variant-numeric:tabular-nums;font-size:16px}
.jump .dot{width:9px;height:9px;flex:0 0 auto;background:currentColor}
.jump .dot--urgent{color:var(--bad)}
.jump .dot--new{color:var(--accent)}
.jump .dot--calm{color:var(--ink-3)}

/* A band is the answer to "does this need me, or is it routine?" */
.band{margin:0 0 8px}
.band__head{
  padding:14px 2px 8px;
  border-bottom:3px solid var(--ink);
  margin-bottom:2px;
}
.band__head h2{
  margin:0;font-size:16px;font-weight:700;letter-spacing:.02em;
}
.band__head p{margin:3px 0 0;font-size:14.5px;color:var(--ink-2)}
.band--calm .band__head{border-bottom-color:var(--rule)}

/* A group folds. 55 enquiries you have not started is a wall; 55 you can put
   away with one tap is a queue. */
.group{margin:0 0 14px;border-bottom:1px solid var(--line)}
.group > summary{
  position:sticky;top:var(--top-h);z-index:10;
  list-style:none;cursor:pointer;
  display:flex;align-items:center;gap:11px;
  min-height:var(--tap);padding:10px 12px;
  background:var(--paper);border-bottom:1px solid var(--line);
  font-size:16px;font-weight:700;letter-spacing:.01em;
}
.group > summary::-webkit-details-marker{display:none}
.group > summary:active{background:var(--sunk)}
.group__n{
  flex:0 0 auto;min-width:34px;padding:2px 6px;text-align:center;
  border:2px solid currentColor;border-radius:2px;
  font-size:15px;font-variant-numeric:tabular-nums;
}
.group--urgent .group__n{color:var(--bad)}
.group--new .group__n{color:var(--accent)}
.group--calm .group__n{color:var(--ink-2)}
.group__fold{
  margin-left:auto;flex:0 0 auto;
  font-size:13px;font-weight:600;color:var(--ink-3);
  display:flex;align-items:center;gap:7px;
}
.group__fold::after{
  content:"";width:9px;height:9px;
  border-right:2.5px solid currentColor;border-bottom:2.5px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .12s linear;
}
.group[open] > summary .group__fold::after{
  transform:rotate(-135deg) translate(-2px,-2px);
}
.group__end{
  padding:12px 4px 16px;font-size:14.5px;color:var(--ink-3);text-align:center;
}

/* ============================ the card =================================== */

.card{
  display:block;position:relative;
  background:var(--card);
  border:1px solid var(--line);
  border-left:4px solid var(--rule);
  border-radius:var(--r);
  padding:12px 34px 12px 13px;
  margin:8px 0;
  color:var(--ink);text-decoration:none;
}
.card:active{background:var(--sunk)}
.card--urgent{border-left-color:var(--bad)}
.card--new{border-left-color:var(--accent)}
.card--calm{border-left-color:var(--rule)}

.card__top{
  display:flex;align-items:center;gap:8px 10px;margin-bottom:7px;
  flex-wrap:wrap;min-width:0;
}
.card__pos{
  margin-left:auto;font-size:13px;font-weight:600;color:var(--ink-3);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.card__who{
  font-size:20px;font-weight:700;letter-spacing:-.015em;line-height:1.2;
}

/* The customer's own words. The most valuable thing on the screen, so it is
   set as speech: ruled off, at reading size, in full ink. */
.card__said{
  margin:8px 0 0;padding:1px 0 1px 12px;
  border-left:3px solid var(--rule);
  font-size:17px;line-height:1.4;color:var(--ink);
}
.card__said::before{content:"\201C"}
.card__said::after{content:"\201D"}
/* Four lines is as much as a card can carry and still be scanned. Nothing is
   lost - the whole message is one tap away on their card. */
.card .card__said,.card .card__note{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;
  overflow:hidden;
}
.card--urgent .card__said{border-left-color:var(--bad)}
.card--new .card__said{border-left-color:var(--accent)}

/* System-written cards do not get quote marks. The assistant is not a person
   and must not be dressed as one. */
.card__note{margin:7px 0 0;font-size:16.5px;line-height:1.4;color:var(--ink)}

.card__meta{
  margin-top:9px;display:flex;flex-wrap:wrap;gap:3px 14px;
  font-size:15px;color:var(--ink-2);font-variant-numeric:tabular-nums;
}
.card__meta .where{font-weight:600;color:var(--ink-2)}
.card__go{
  position:absolute;right:13px;top:50%;
  width:10px;height:10px;margin-top:-5px;
  border-right:2.5px solid var(--ink-3);border-top:2.5px solid var(--ink-3);
  transform:rotate(45deg);
}

/* ============================ conversation =============================== */
/* Requirement, and the whole reason this app exists: a message that never left
   the building must never read like one the customer received. */

.msg{
  position:relative;
  border:1px solid var(--line);border-radius:var(--r);
  padding:11px 13px;margin:0 0 10px;
  background:var(--card);
}
.msg__label{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-bottom:6px;
}
.msg__who{
  font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;
}
.msg__when{
  margin-left:auto;font-size:13.5px;color:var(--ink-3);
  font-variant-numeric:tabular-nums;
}
.msg__text{
  margin:0;font-size:17px;line-height:1.45;white-space:pre-wrap;color:var(--ink);
}
.msg__why{margin:8px 0 0;font-size:15px;line-height:1.4}

/* THEM: full card, left, ink-ruled. Somebody real said this. */
.msg--in{border-left:4px solid var(--ink)}
.msg--in .msg__who{color:var(--ink-2)}

/* SENT: indented, green-ruled, filled label. It reached them. */
.msg--sent{
  margin-left:26px;border-left:4px solid var(--accent);
  background:var(--card);
}
.msg--sent .msg__who{color:var(--accent)}

/* DRAFT: recessed, dashed, no fill of its own - visibly not a message yet. */
.msg--ghost{
  margin-left:26px;
  background:var(--sunk);
  border:2px dashed var(--rule);
}
.msg--ghost .msg__who{color:var(--ink-2)}
.msg--ghost .msg__text{color:var(--ink)}

/* NOT SENT: red, solid-stamped, and it says so before you read the message. */
.msg--failed{
  margin-left:26px;
  background:var(--sunk);
  border:2px solid var(--bad);border-left-width:6px;
}
.msg--failed .msg__why{color:var(--bad)}

/* IN FLIGHT: amber, because we genuinely do not know. */
.msg--unknown{
  margin-left:26px;
  background:var(--sunk);
  border:2px solid var(--warn);border-left-width:6px;
}
.msg--unknown .msg__who{color:var(--warn)}
.msg--unknown .msg__why{color:var(--warn)}

/* ============================ the refusal ================================ */
/* Not an error. The system declining to invent something. It should read as
   care, so it is built like a small notice with its own heading, not like a
   red box with a sentence in it. */

.refusal{
  background:var(--card);
  border:1px solid var(--line);border-top:4px solid var(--accent);
  border-radius:var(--r);padding:14px;
}
.refusal h3{
  margin:0 0 8px;font-size:16px;font-weight:700;
  display:flex;align-items:center;gap:9px;
}
.refusal h3 svg{width:20px;height:20px;color:var(--accent);flex:0 0 auto}
.refusal__what{
  margin:0;padding:10px 12px;
  background:var(--sunk);border-left:3px solid var(--rule);
  font-size:17px;line-height:1.4;color:var(--ink);
}
.refusal__why{margin:10px 0 0;font-size:15px;line-height:1.45;color:var(--ink-2)}

/* ============================ key/value =================================== */

.kv{margin:0;font-size:16px}
.kv div{
  display:flex;gap:12px;padding:9px 0;border-bottom:1px solid var(--line);
}
.kv div:last-child{border-bottom:0}
.kv dt{flex:0 0 96px;color:var(--ink-2);font-size:15px}
.kv dd{margin:0;flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.kv a{color:var(--accent);font-weight:600}

.linkbox{
  display:block;margin-top:8px;padding:10px 12px;
  background:var(--sunk);border:1px dashed var(--rule);border-radius:var(--r);
  font-size:14.5px;line-height:1.4;color:var(--ink);
  overflow-wrap:anywhere;word-break:break-all;
}

/* ============================ sign-in ==================================== */

.gate{max-width:400px;margin:6vh auto 0;padding:0 2px}
.gate__mark{
  width:44px;height:6px;background:var(--accent);margin-bottom:18px;
}
.gate h2{margin:0 0 6px;font-size:26px;font-weight:700;letter-spacing:-.02em}
.gate p{margin:0 0 22px;font-size:16px;color:var(--ink-2);line-height:1.45}

/* ============================ misc ======================================= */

.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
.stack{display:grid;gap:10px}
.vh{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
form.inline{display:inline}

/* --- late additions ------------------------------------------------------ */

.group{scroll-margin-top:calc(var(--top-h) + 4px)}
.band{scroll-margin-top:calc(var(--top-h) + 4px)}

code{
  font:600 15px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  background:var(--sunk);border:1px solid var(--line);border-radius:2px;
  padding:1px 5px;overflow-wrap:anywhere;
}

/* The .btn inside a .btn-row is auto-width; the theme group wants three even
   thirds and the resurface row wants four. flex-basis does both. */
#theme .btn{flex:1 1 30%}

/* Long single tokens - an onboarding URL, an email - must never widen the
   page. Everything that can carry one is told to break. */
.kv dd,.card__meta span,.row__sub span{min-width:0}


/* A refusal must not wear a confirmation's colours. `.notice` keeps its
   existing frame; only the rule and the mark change, so the two read as the
   same kind of message with opposite outcomes. */
.notice--ok   { border-left-color: var(--accent); }
.notice--ok   .notice__mark { color: var(--accent); }
.notice--bad  { border-left-color: var(--bad); }
.notice--bad  .notice__mark { color: var(--bad); }


/* ============================ prompts & runs =============================
   Two screens about the assistant: the standing instructions, and one
   execution of one of them.

   Nothing new is invented here. A prompt is a docket like everything else, a
   tool call is a card, and a proposed surface wears the same recessed dashed
   frame an unsent draft wears in the conversation - because it IS an unsent
   thing, and the whole product rests on that never being blurred. Every
   colour below comes from the token set above and means what it means
   everywhere else: accent for a person or a safe outcome, warn for
   unfinished, bad for broken, ink-2/3 for the system talking about itself.
   ========================================================================= */

/* The thing worth saying before anything else on either screen: the server has
   four reads and one write, and the write is a card. Framed like the refusal -
   care, not alarm - because that is what it is. */
.safety{
  background:var(--card);
  border:1px solid var(--line);border-top:4px solid var(--accent);
  border-radius:var(--r);padding:14px;margin:0 0 16px;
}
.safety h2{
  margin:0 0 7px;font-size:17px;font-weight:700;line-height:1.25;
  display:flex;align-items:center;gap:9px;
}
.safety h2 svg{width:21px;height:21px;color:var(--accent);flex:0 0 auto}
.safety p{margin:0;font-size:15.5px;line-height:1.45;color:var(--ink-2)}

/* ---- one prompt note ---------------------------------------------------- */

.prompt{
  background:var(--card);
  border:1px solid var(--line);border-top:4px solid var(--ink);
  border-radius:var(--r);padding:var(--pad);margin:0 0 18px;
}
.prompt--broken{border-top-color:var(--bad)}
.prompt__name{
  margin:2px 0 0;font-size:21px;font-weight:700;letter-spacing:-.015em;
  line-height:1.2;
}

/* When it next fires. The one line that has to be readable at arm's length, so
   it gets a block of its own rather than a grey line of metadata. A note with
   no schedule says so in words - a blank here would read as "soon". */
.fire{
  margin:11px 0 0;padding:10px 12px;
  background:var(--sunk);border-left:4px solid var(--accent);
  border-radius:var(--r);
}
.fire__when{
  display:block;font-size:18px;font-weight:700;line-height:1.25;color:var(--ink);
}
.fire__why{display:block;margin-top:3px;font-size:15px;color:var(--ink-2)}
.fire--tap{border-left-color:var(--rule)}
.fire--broken{border-left-color:var(--warn)}
.fire--broken .fire__when{color:var(--warn)}

/* The instruction, as written. Recessed and dashed: this is text somebody
   authored elsewhere, shown here, not a control on this screen. */
.brief{
  margin:12px 0 0;padding:11px 13px;
  background:var(--sunk);border:1px dashed var(--rule);border-radius:var(--r);
}
.brief__label{
  margin:0 0 6px;font-size:11.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.1em;color:var(--ink-2);
}
.brief__text{
  margin:0;font-size:16.5px;line-height:1.45;color:var(--ink);
  white-space:pre-wrap;
}

.prompt__runs{margin-top:18px;border-top:1px solid var(--line);padding-top:12px}
.prompt__runs-label{
  margin:0;font-size:11.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.1em;color:var(--ink-2);
}
/* Never run is not the same fact as ran and found nothing, and it does not get
   the same sentence. objects/agent run.md rule 5. */
.prompt__never{
  margin:9px 0 0;padding:14px 12px;text-align:center;
  background:var(--sunk);border:1px dashed var(--rule);border-radius:var(--r);
  font-size:16px;line-height:1.4;color:var(--ink);
}

/* ---- one past run, as a row --------------------------------------------- */

.runline{
  display:flex;align-items:center;gap:12px;
  min-height:64px;padding:12px 12px 12px 13px;margin:9px 0 0;
  background:var(--card);
  border:1px solid var(--line);border-left:4px solid var(--rule);
  border-radius:var(--r);
  color:var(--ink);text-decoration:none;
}
.runline:active{background:var(--sunk)}
.runline--bad{border-left-color:var(--bad)}
.runline__main{flex:1 1 auto;min-width:0}
.runline__what{display:flex;align-items:center;gap:8px 10px;flex-wrap:wrap}
.runline__by{font-size:14px;color:var(--ink-3)}
.runline__sub{
  display:block;margin-top:5px;font-size:15px;line-height:1.35;color:var(--ink-2);
}
.runline__when{
  display:block;margin-top:4px;font-size:14px;color:var(--ink-3);
  font-variant-numeric:tabular-nums;
}

/* ---- the result of one run ---------------------------------------------- */
/* Four outcomes, four faces. The one that matters most is --none: a run that
   read the business and proposed nothing is a good morning, and it must not
   wear the colours of one that broke. */

.result{
  background:var(--card);
  border:1px solid var(--line);border-top:5px solid var(--rule);
  border-radius:var(--r);padding:16px var(--pad);margin:0 0 16px;
}
.result__n{
  margin:0;font-size:40px;font-weight:700;line-height:1;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;color:var(--ink);
}
.result__what{
  margin:6px 0 0;font-size:18px;font-weight:600;line-height:1.3;color:var(--ink);
}
.result__why{margin:10px 0 0;font-size:15.5px;line-height:1.45;color:var(--ink-2)}
.result--good{border-top-color:var(--accent)}
.result--good .result__n{color:var(--accent)}
.result--none{border-top-color:var(--rule)}
.result--running{border-top-color:var(--warn)}
.result--running .result__n{font-size:28px;color:var(--warn)}
.result--bad{border-top-color:var(--bad)}
.result--bad .result__n{font-size:28px;color:var(--bad)}

/* ---- the tool calls ------------------------------------------------------ */
/* The evidence, and the reason this screen exists. An assistant that says
   three people are waiting has either read three rows or written a sentence,
   and this block is the only place a person can tell which. So: numbered, at
   reading size, arguments shown, row count loud, never behind a toggle. */

.call{
  background:var(--card);
  border:1px solid var(--line);border-left:4px solid var(--rule);
  border-radius:var(--r);padding:12px 13px;margin:0 0 10px;
}
.call--held{border-left-color:var(--accent)}
.call--refused,.call--odd{border-left-color:var(--warn)}

.call__head{display:flex;gap:10px;align-items:flex-start}
.call__n{
  flex:0 0 auto;margin-top:2px;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:26px;height:26px;padding:0 5px;
  border:2px solid var(--rule);border-radius:2px;
  font-size:14px;font-weight:700;color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
.call__said{
  min-width:0;font-size:17.5px;font-weight:700;line-height:1.3;
  letter-spacing:-.01em;color:var(--ink);
}

/* Everything under the headline lines up under it, so a call reads as one
   block rather than four stacked sentences. */
.call__meta,.args,.call__answer,.call__why,.call__none{padding-left:36px}
.call__meta{
  margin-top:5px;display:flex;flex-wrap:wrap;gap:3px 12px;
  font-size:14px;color:var(--ink-3);font-variant-numeric:tabular-nums;
}
/* The literal tool name is kept beside the plain-English one on purpose: the
   record has to stay checkable against mcp.md by somebody who knows it. */
.call__tool{
  font:600 13.5px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  color:var(--ink-2);overflow-wrap:anywhere;min-width:0;
}

.args{margin-top:9px;display:flex;flex-wrap:wrap;gap:6px}
.arg{
  display:inline-flex;align-items:baseline;gap:7px;
  max-width:100%;min-width:0;padding:4px 9px;
  background:var(--sunk);border:1px solid var(--line);border-radius:2px;
  font-size:15px;line-height:1.35;color:var(--ink);overflow-wrap:anywhere;
}
.arg b{
  flex:0 0 auto;font-size:13px;font-weight:700;text-transform:uppercase;
  letter-spacing:.06em;color:var(--ink-2);
}

.call__answer{
  margin:10px 0 0;display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;
}
.call__rows{
  font-size:26px;font-weight:700;line-height:1;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--ink);
}
.call__answer-t{min-width:0;font-size:16px;line-height:1.35;color:var(--ink-2)}
.call__why{margin:9px 0 0;font-size:15.5px;line-height:1.4;color:var(--ink)}
.call__none{margin:9px 0 0;font-size:15px;line-height:1.4;color:var(--ink-3)}
.call__detail{
  margin:9px 0 0 36px;padding:9px 11px;
  background:var(--sunk);border-left:3px solid var(--rule);border-radius:2px;
  font-size:14.5px;line-height:1.4;color:var(--ink-2);overflow-wrap:anywhere;
}
.call--held .call__detail{border-left-color:var(--accent)}
.call--refused .call__detail{border-left-color:var(--warn)}

/* ---- a proposed card ----------------------------------------------------- */
/* Same grammar as an unsent draft in the conversation: recessed, dashed, no
   fill of its own. A suggestion must never be mistakeable for a thing that
   happened to a customer. */

.propose{
  background:var(--sunk);
  border:2px dashed var(--rule);border-radius:var(--r);
  padding:12px 13px;margin:0 0 10px;
}
.propose--closed{border-style:solid;border-color:var(--line)}
.propose__state{margin:9px 0 0;font-size:15px;line-height:1.4;color:var(--ink-2)}
.propose .btn{margin-top:12px}

/* ============================ the assistant ============================== */
/* The chat screen. Nothing new is invented here - the answer wears the docket
   card, the question wears the same frame a customer's message wears, and a
   failed run wears the "this did not happen" frame from the conversation
   above. Only one thing is genuinely new: a tool call.

   A call is EVIDENCE, not chat. So it is recessed like a draft, ruled like a
   card, set smaller than the answer it sits under, and it never carries the
   accent unless something was actually written. It is always on the screen -
   folding it away would leave a claim with no receipt, which is the failure
   this whole product is built against - but the payload it returned is folded,
   capped in height, and wraps rather than widening the page. */

.chat-ask{border-top:4px solid var(--ink)}
.chat-ask--off{border-top-color:var(--warn)}
.chat-ask .field{margin-bottom:12px}
.chat-ask textarea{min-height:72px}
/* Off is off, and it says so in full ink rather than in a grey that reads as
   "loading". Same treatment a disabled button gets: sunk, dashed, legible. */
.chat-ask textarea:disabled{
  background:var(--sunk);border-style:dashed;
  color:var(--ink);-webkit-text-fill-color:var(--ink);
  opacity:1;cursor:not-allowed;
}
.chat-ask textarea:disabled::placeholder{
  color:var(--ink);-webkit-text-fill-color:var(--ink);opacity:1;
}
.chat-ask .hint{margin-top:10px}

.chat-suggest{display:grid;gap:8px;margin:12px 0 4px}
.chat-suggest form{margin:0}
.chat-suggest .btn{justify-content:flex-start;text-align:left;padding:12px 14px}

.chat-ex{margin:0 0 4px}
.chat-ex + .chat-ex{
  margin-top:18px;padding-top:14px;border-top:1px solid var(--line);
}

.chat-answer{
  background:var(--card);
  border:1px solid var(--line);
  border-top:4px solid var(--ink);
  border-radius:var(--r);
  padding:12px 13px;margin:0 0 10px;
}
.chat-answer .msg__who{color:var(--ink-2)}

/* Not an answer, and it must not be readable as one. */
.chat-fail{
  background:var(--sunk);
  border:2px solid var(--bad);border-left-width:6px;
  border-radius:var(--r);
  padding:11px 13px;margin:0 0 10px;
}
.chat-fail__why{
  margin:8px 0 0;padding:8px 10px;
  background:var(--card);border:1px solid var(--line);border-radius:2px;
  font-size:15px;line-height:1.4;color:var(--ink-2);
  overflow-wrap:anywhere;word-break:break-word;
}

.chat-looks{margin:0 0 6px}
.chat-looks__head{
  display:flex;align-items:baseline;gap:6px 9px;flex-wrap:wrap;
  margin:12px 2px 7px;
  font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;
  color:var(--ink-2);
}
.chat-looks__n{
  margin-left:auto;text-transform:none;letter-spacing:.01em;
  font-size:13.5px;font-weight:600;color:var(--ink-3);
  font-variant-numeric:tabular-nums;
}
.chat-looks__none{
  text-transform:none;letter-spacing:0;font-weight:500;
  font-size:15px;color:var(--ink-2);
}

.chat-look{
  background:var(--sunk);
  border:1px solid var(--line);
  border-left:4px solid var(--rule);
  border-radius:var(--r);
  padding:10px 12px;margin:0 0 8px;
}
.chat-look--wrote{border-left-color:var(--accent)}
.chat-look--bad{border-left-color:var(--bad)}

.chat-look__top{
  display:flex;align-items:baseline;gap:7px 10px;flex-wrap:wrap;min-width:0;
}
.chat-look__what{
  font-size:16.5px;font-weight:600;line-height:1.3;color:var(--ink);
  min-width:0;overflow-wrap:anywhere;
}
.chat-look__n{
  margin-left:auto;font-size:15px;font-weight:600;color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
.chat-look__args{
  margin:5px 0 0;font-size:15px;line-height:1.4;color:var(--ink-2);
  overflow-wrap:anywhere;
}
.chat-look__why{
  margin:5px 0 0;font-size:15px;line-height:1.4;color:var(--bad);
  overflow-wrap:anywhere;
}

.chat-look__raw{margin-top:6px}
.chat-look__raw > summary{
  list-style:none;cursor:pointer;
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  min-height:var(--tap);padding:6px 2px;
  font-size:15px;font-weight:600;color:var(--ink-2);
}
.chat-look__raw > summary::-webkit-details-marker{display:none}
.chat-look__raw > summary::after{
  content:"";flex:0 0 auto;width:9px;height:9px;
  border-right:2.5px solid currentColor;border-bottom:2.5px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);
}
.chat-look__raw[open] > summary::after{
  transform:rotate(-135deg) translate(-2px,-2px);
}
.chat-look__raw code{background:var(--card)}
/* Up to 2,000 characters of JSON, and it must not be able to widen the
   document or run off the bottom of it. It wraps, it is capped, it scrolls
   inside its own box. */
.chat-look__pre{
  max-height:220px;overflow:auto;-webkit-overflow-scrolling:touch;
  background:var(--card);border:1px solid var(--line);border-radius:2px;
  padding:8px 10px;max-width:100%;
}
.chat-look__pre pre{
  margin:0;color:var(--ink);
  font:400 13.5px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;
}

.chat-can{margin:0;padding:0;list-style:none}
.chat-can li{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:3px 8px;
  padding:9px 0;border-bottom:1px solid var(--line);
}
.chat-can li:last-child{border-bottom:0}
.chat-can strong{
  flex:1 1 100%;font-size:16.5px;font-weight:600;line-height:1.3;color:var(--ink);
}
.chat-can span:not(.stamp){font-size:15px;line-height:1.4;color:var(--ink-2)}
.chat-can__not{
  margin:12px 0 0;padding-top:11px;border-top:1px solid var(--rule);
  font-size:15px;line-height:1.45;color:var(--ink-2);
}

.chat-threads{margin-top:12px}
.chat-threads__q{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  overflow:hidden;
}

/* A long instruction folds. Saxon's two real notes are a screen and a half of
   text each, and unfolded they push the Run button, the run history and every
   tool call under the fold - on screens whose whole job is to show those. The
   summary is a full tap target and the fold state is written in words, the way
   a group on the surface writes it. */
.brief > summary{
  list-style:none;cursor:pointer;
  display:flex;align-items:center;gap:10px;
  min-height:var(--tap);margin:-11px -13px 0;padding:11px 13px;
}
.brief > summary::-webkit-details-marker{display:none}
.brief > summary:active{background:var(--line)}
.brief > summary .brief__label{margin:0;min-width:0}
.brief[open] > summary{margin-bottom:7px}
.brief__fold{
  margin-left:auto;flex:0 0 auto;
  font-size:13px;font-weight:600;color:var(--ink-3);
  display:flex;align-items:center;gap:7px;
}
.brief__fold::after{
  content:"";width:9px;height:9px;
  border-right:2.5px solid currentColor;border-bottom:2.5px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .12s linear;
}
.brief[open] > summary .brief__fold::after{
  transform:rotate(-135deg) translate(-2px,-2px);
}

/* A run that proposed nothing while the gate held a card, or while the server
   refused one of its questions, has more to say than "nothing today". These two
   lines carry that under the headline, ruled in the colour the thing they
   describe wears further down the page. */
.result__note{
  margin:10px 0 0;padding:8px 11px;
  background:var(--sunk);border-left:3px solid var(--rule);border-radius:2px;
  font-size:15.5px;line-height:1.4;color:var(--ink);
}
.result__note--held{border-left-color:var(--accent)}
.result__note--refused{border-left-color:var(--warn)}

/* The chat's waiting note. Hidden until the form is actually submitted, so it
   never states a delay that is not happening. Same amber as an unarmed rule:
   this is a hold, not a fault. */
.chat-wait{
  margin:.6rem 0 0; padding:.55rem .7rem;
  background:var(--sunk); border-left:4px solid var(--warn);
  border-radius:var(--r); color:var(--ink); font-size:.95rem; line-height:1.45;
}

/* The instruction and a disabled Run button are both dashed boxes; without
   this they stack edge to edge and read as one control. */
.prompt form{margin-top:12px}

/* A line the gate stopped and the assistant then rewrote. Deliberately the
   quietest of the three notes: nothing is missing, so it must not carry the
   weight of `--held` (a card that never got made) or `--refused` (a question
   the server would not answer). */
.result__note--fixed{border-left-color:var(--ink-2)}

/* The assistant's suggested line, on the card. Dashed and sunk, the same
   grammar every unsent draft on this dashboard wears - it must not read as
   something that has already gone out. */
.card__ghost{
  margin:.45rem 0 .1rem; padding:.5rem .65rem;
  background:var(--sunk); border:1px dashed var(--rule); border-radius:var(--r);
  color:var(--ink); font-size:.95rem; line-height:1.45;
}

/* ============================================================================
   The content surface.

   Everything below was referenced by `content.html` and `gallery.html` and
   declared nowhere: `.tabrow`, `.grid`, `.tile`, `.filters` and `.note` had no
   rules at all, so the whole area rendered as unstyled flow. Read on a phone at
   a job site that is not a cosmetic problem - a gallery of full-width stacked
   images with no grid is a page you scroll for a minute to see six photographs.

   Same grammar as the rest of the file: squared corners, ruled panels, colour
   only where it carries meaning, and every tap target at least --tap.
   ========================================================================= */

/* Three views of one area. A row of tabs rather than a select: a select needs a
   submit and hides two of the three names until you open it. */
.tabrow{
  display:flex;gap:6px;margin:0 0 14px;
  border-bottom:2px solid var(--line);
}
.tabrow a{
  flex:1 1 0;min-width:0;
  display:flex;align-items:center;justify-content:center;
  min-height:var(--tap);padding:10px 8px;
  font-size:16px;font-weight:600;color:var(--ink-2);text-decoration:none;
  border-bottom:3px solid transparent;margin-bottom:-2px;
}
.tabrow a.on{color:var(--ink);border-bottom-color:var(--ink)}
.tabrow a:active{background:var(--sunk)}

.note{margin:18px 0 0;font-size:14px;color:var(--ink-3)}
.note--bad{color:var(--warn)}
.note a{color:var(--accent);font-weight:600}

/* THE POST'S OWN PICTURE. Full bleed inside the card, capped so a portrait
   render cannot push the words off a 390px screen, and `background` so the box
   is visible while the bytes are still arriving over mobile data. */
.card__shot{
  display:block;width:100%;height:auto;max-height:52vh;
  /* `contain`, NEVER `cover`. The picture IS the post - a rendered card's own
     call-to-action sits at its foot, and cropping to fill a box hides the
     argument the post makes. A portrait render letterboxes on the sunk ground
     rather than losing its bottom third. */
  object-fit:contain;object-position:top;
  background:var(--sunk);border:1px solid var(--line);
  margin:0 0 10px;
}

/* The stop, folded. Kept as a `<details>` because that is the fallback the
   dialog is built on top of - with script off this is the whole control. */
.stopfold{margin-top:10px}
.stopfold > summary{list-style:none;cursor:pointer}
.stopfold > summary::-webkit-details-marker{display:none}
.stopfold[open] > summary{margin-bottom:10px}
.stopfold form{
  padding:12px;background:var(--sunk);
  border:1px solid var(--line);border-left:3px solid var(--bad);
}
.stopfold input[type=text]{width:100%;margin:0 0 10px}

/* The same form, promoted to a modal where the browser has one. Sized for a
   phone first and only then allowed to grow. */
.stopdlg{
  width:min(440px,calc(100vw - 24px));
  padding:16px;border:1px solid var(--rule);border-radius:var(--r);
  background:var(--card);color:var(--ink);
}
.stopdlg::backdrop{background:rgba(0,0,0,.55)}
.stopdlg h2{margin:0 0 10px;font-size:20px;font-weight:700;letter-spacing:-.01em}
.stopdlg form{padding:0;background:none;border:0}
.stopdlg input[type=text]{width:100%;margin:0 0 12px}

/* --- the gallery ---------------------------------------------------------- */

.filters{margin:0 0 12px}
.filters input[type=search]{width:100%;margin:0 0 10px}

/* Two columns at 390px. `auto-fill` rather than a fixed count so the same rule
   serves a phone held sideways and a desk browser without a media query. */
.grid{
  display:grid;gap:8px;margin:4px 0 0;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
}
.tile{margin:0;background:var(--card);border:1px solid var(--line)}
.tile img{
  display:block;width:100%;
  /* `height:auto` IS LOAD-BEARING. The tag carries width/height attributes, and
     a browser maps those to a presentational `height:300px` that beats
     `aspect-ratio` - the tile rendered 177x300 instead of 177x133, so six
     photographs filled a phone screen. Measured, not guessed. */
  height:auto;aspect-ratio:4/3;object-fit:cover;
  background:var(--sunk);
}
.tile figcaption{
  padding:7px 8px;font-size:13.5px;line-height:1.3;color:var(--ink-2);
  overflow-wrap:anywhere;
}
.tile__why{
  display:block;margin-top:3px;font-size:12.5px;font-weight:600;color:var(--warn);
}

/* The facets. A chip is a link, so a filtered gallery has a URL she can send
   us, and every chip carries its own count - a filter that cannot say how many
   it will leave is a filter you press twice. */
.facet{margin:0 0 12px}
.facet__head{
  display:block;margin:0 0 6px;
  font-size:12.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);
}
.facet__chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{
  display:inline-flex;align-items:center;gap:6px;
  min-height:38px;padding:6px 11px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  font-size:15px;color:var(--ink);text-decoration:none;
}
.chip b{font-variant-numeric:tabular-nums;font-weight:700;color:var(--ink-3)}
.chip.on{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.chip.on b{color:var(--paper)}
.chip:active{background:var(--sunk)}
.facet__note{margin:6px 0 0;font-size:13px;line-height:1.35;color:var(--ink-3)}

/* --- level 1, on the client's own card ------------------------------------
   Deliberately a DIFFERENT surface inside the same card: sunk, ruled in the
   structural grey, and tagged. Oscar has to be able to tell at a glance which
   half of the screen the client can see, because the whole reason he stands on
   her card is to catch it lying to her. */
.oscar-bar{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  margin:0 0 14px;padding:8px;background:var(--sunk);border:1px dashed var(--rule);
}
.oscar-bar__tag,.l1__tag{
  flex:0 0 auto;padding:3px 7px;background:var(--ink);color:var(--paper);
  font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
}
.oscar-bar a{
  min-height:38px;display:inline-flex;align-items:center;padding:6px 11px;
  background:var(--card);border:1px solid var(--line);
  font-size:15px;font-weight:600;color:var(--ink);text-decoration:none;
}
.oscar-bar a.on{background:var(--ink);border-color:var(--ink);color:var(--paper)}

.l1{
  margin:12px -13px -11px;padding:11px 13px;
  background:var(--sunk);border-top:1px dashed var(--rule);
}
.l1__head{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin:0 0 8px}
.l1__ref{font-size:14px;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
.l1__flag{
  margin:0 0 10px;padding:9px 11px;background:var(--card);
  border-left:3px solid var(--bad);font-size:15px;line-height:1.4;
}
.l1__said{display:block;margin:4px 0 8px;color:var(--ink-2)}
.l1__flag input[type=text]{width:100%;margin:0 0 8px}

/* One row per lane, STACKED. A table put the channel, the state and two
   buttons on one line and pushed the card to 420px inside a 390px screen -
   measured on Blue's own cards, not guessed. */
.lanes{list-style:none;margin:0;padding:0;font-size:14.5px}
.lane{padding:8px 0;border-bottom:1px solid var(--line)}
.lane:last-child{border-bottom:0}
.lane__top{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;
}
.lane__top b{font-weight:700;color:var(--ink-2);overflow-wrap:anywhere}
.lane__top span{color:var(--ink)}
.lane .btn-row{margin-top:7px}
.lane .btn-row form{flex:1 1 130px;min-width:0;display:flex}
.lane .btn-row .btn{width:100%;min-height:40px;padding:8px 10px;font-size:14.5px}
.lane--bad .lane__top b{color:var(--bad)}
.lane__why{margin:6px 0 0;font-size:13.5px;line-height:1.4;color:var(--ink-2)}
.lane__fail{
  margin:6px 0 0;padding:7px 8px;background:var(--card);
  border-left:3px solid var(--bad);
  font-size:12.5px;line-height:1.4;white-space:pre-wrap;overflow-wrap:anywhere;
}

.l1 > form{margin-top:10px}
.l1__edit{margin-top:10px}
.l1__edit > summary{list-style:none;cursor:pointer}
.l1__edit > summary::-webkit-details-marker{display:none}
.l1__edit form{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px}
.l1__edit select{flex:0 0 auto;min-height:var(--tap)}
.l1__edit input[type=text]{flex:1 1 160px;min-width:0}
.l1__edit .btn{width:auto;flex:0 0 auto}

/* The refusal page: a child process's own words, wrapped rather than cut. */
.refusal__stream{
  margin:0;padding:10px 11px;background:var(--sunk);
  border-left:3px solid var(--bad);
  font-size:13px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere;
}

/* The facet strip, folded. `.brief` already carries the fold's grammar; this
   only holds the chips apart once it is open, and keeps the last one clear of
   the grid below. */
.facets > summary{display:flex;align-items:center;gap:10px}
.facets .facet{margin-top:12px}
.facets .facet:last-of-type{margin-bottom:2px}

/* A logo fitted whole rather than filled. Nineteen of Blue's sixty-one usable
   files are wordmarks, and a cropped wordmark reads as our gallery being broken
   rather than as her brand. */
.tile--whole img{object-fit:contain;padding:8px;background:var(--card)}
