/* ===========================================================================
   apublished — the design system.

   One stylesheet, no build step, served as-is. It carries the landing page's
   vocabulary into the console, because they are the same product and a person
   who signs up should not feel like they have arrived somewhere else.

   What changes between the two is the SURFACE, not the palette:

     landing page   cobalt ground, bone text. A poster. Read once.
     console        bone ground, ink text. A desk. Read every day.

   Cobalt at full strength across 1400px is right for thirty seconds and wrong
   for eight hours, so in here it demotes to the accent it always was — links,
   the active nav item, the state a row is in.

   Deliberately single-theme. There is no dark mode. See HANDOFF.md: the palette
   IS the identity, and a second one is a second product to maintain.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   FONTS — self-hosted. Files in apps/web/public/fonts, licences beside them.

   Archivo ships as ONE variable font with a WIDTH axis (62.5–125%) as well as a
   weight axis, so "Archivo Condensed" is not a second file — it is the same
   file instantiated at 62.5%. Declaring it as a separate family whose face
   covers only that width is what makes `font-family: "Archivo Condensed"` work
   unchanged everywhere it is already written: the browser clamps the element's
   normal width into the one value the face declares.

   Self-hosted rather than linked, for three reasons that all matter here:
   Google Fonts is a third party on the critical path of the first paint; the
   request leaks every visitor's IP to it; and a page that must open from disk
   with no network cannot depend on it.

   Both faces are SIL Open Font Licence 1.1. Redistribution is permitted; the
   licence texts ship alongside the files, which is the condition.
--------------------------------------------------------------------------- */

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

/* The display face: same file, pinned to the narrow end of the width axis. */
@font-face {
  font-family: 'Archivo Condensed';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 62.5%;
  font-display: swap;
  src: url('/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308,
    U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo Condensed';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 62.5%;
  font-display: swap;
  src: url('/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

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

:root {
  /* --- brand, unchanged from the landing page ---------------------------- */
  --cobalt: #1d2fd4;
  --cobalt-lift: #2a3de8;
  --navy: #070b2e;
  --navy-lift: #0e1440;
  --bone: #f2efe9;
  --bone-2: #e6e2d9;
  --coral: #ff5c35;
  /* Coral, in the two places it must carry contrast rather than provide it.

     #FF5C35 on cobalt is 2.84:1. That is fine when coral is a FILL and ink sits
     on it (6.9:1), which is most of its job — buttons, the proof band, the rule
     under the headline. It is not fine when coral is the text.

     --coral-display  +7%, and visually the same colour. Clears the 3:1 that
                      WCAG asks of text at 24px and up, which is the only size
                      coral is ever set at on a cobalt ground.
     --coral-text     the tint small coral text needs to reach 4.5:1. Visibly
                      lighter, and that is the price of an 11.5px eyebrow being
                      readable. Never use --coral for small text on cobalt. */
  --coral-display: #ff6743;
  --coral-text: #ffa38d;
  --ink: #0a0c1a;
  --slate: #4a4f6b;
  /* Darkened from #767B93, which measured 3.94:1 on --paper. This colour
     carries metadata — table hints, provider names, "never" in a key row — and
     small grey text is exactly where contrast quietly fails. */
  --slate-2: #6c7187;

  /* on-cobalt text */
  --on-cobalt: #f2efe9;
  --on-cobalt-dim: rgba(242, 239, 233, 0.72);
  --hair-cobalt: rgba(242, 239, 233, 0.26);

  /* syntax, derived from the brand hues */
  --c-key: #96a6ff;
  --c-str: #ffb39b;
  --c-num: #f2efe9;
  --c-com: #5b639b;
  --c-verb: #ff5c35;
  --c-ok: #4fd6a0;

  --display:
    "Archivo Condensed", "Avenir Next Condensed", "Helvetica Neue Condensed", "Arial Narrow", "Archivo",
    "Helvetica Neue", sans-serif;
  --sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --pad: clamp(20px, 5vw, 64px);
  --max: 1240px;

  /* --- console additions -------------------------------------------------
     The landing page needs none of these. They exist because a working
     surface has hairlines, panels and a sidebar, and a poster does not. */

  /* Surfaces, lightest to heaviest. */
  --paper: #faf8f4;
  --surface: var(--bone);
  --surface-2: var(--bone-2);

  /* Hairlines. Two weights: one you look through, one you stop at. */
  --line: rgba(10, 12, 26, 0.11);
  --line-strong: rgba(10, 12, 26, 0.24);
  /* The boundary of something you can operate — an input, a ghost button, a
     month-step arrow. WCAG asks 3:1 of those, which 0.24 does not reach (1.73:1);
     a control whose edge you cannot find is a control you cannot use. Structural
     rules keep --line-strong, because a table underline is not a control. */
  --edge: rgba(10, 12, 26, 0.45);

  /* Semantic colours, tuned for INK-ON-BONE. The syntax palette above is for
     bone-on-navy and fails contrast the other way round — --c-ok at 4.5:1
     against navy is 1.6:1 against bone, which is not a colour, it is a rumour. */
  --ok: #0f7a55;
  --ok-wash: #e2f2ea;
  --warn: #8a5200;
  --warn-wash: #fbeedd;
  --bad: #c1360f;
  --bad-wash: #fce6df;
  --info: var(--cobalt);
  --info-wash: #e4e6fb;
  --idle: var(--slate-2);
  --idle-wash: #eae8e2;

  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(10, 12, 26, 0.05), 0 8px 24px -12px rgba(10, 12, 26, 0.18);

  --sidebar: 236px;
  --topbar: 60px;

  /* A four-step scale. More than four and nobody remembers which is which. */
  --s1: 8px;
  --s2: 16px;
  --s3: 28px;
  --s4: 48px;
}

/* ===========================================================================
   Base
   =========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--cobalt);
}

:focus-visible {
  outline: 3px solid var(--coral);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 99;
  background: var(--coral);
  color: var(--ink);
  padding: 12px 20px;
  font-weight: 700;
  text-decoration: none;
}
.skip:focus {
  left: 0;
}

.inner {
  max-width: var(--max);
  margin: 0 auto;
}

/* Say it once, to screen readers only. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ===========================================================================
   Type primitives — shared with the landing page
   =========================================================================== */

.dsp {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: 0.9;
  margin: 0;
  text-wrap: balance;
}

.eyebrow {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 var(--s2);
  color: var(--slate-2);
}

.lede {
  font-size: clamp(15px, 1.5vw, 17px);
  margin: 0;
  max-width: 52ch;
  color: var(--slate);
}

.mono {
  font-family: var(--mono);
}

.muted {
  color: var(--slate);
}

.num {
  font-variant-numeric: tabular-nums;
}

.wordmark {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  text-decoration: none;
  color: inherit;
}

/* ===========================================================================
   Buttons
   =========================================================================== */

.btn {
  display: inline-block;
  text-decoration: none;
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  padding: 10px 20px;
  border-radius: 40px;
  border: 2px solid transparent;
  white-space: nowrap;
  cursor: pointer;
  background: none;
  color: inherit;
  line-height: 1.2;
}
.btn-coral {
  background: var(--coral);
  color: var(--ink);
}
.btn-coral:hover {
  background: #ff7452;
}
.btn-cobalt {
  background: var(--cobalt);
  color: var(--bone);
}
.btn-cobalt:hover {
  background: var(--cobalt-lift);
}
.btn-ghost {
  border-color: var(--edge);
  color: var(--ink);
}
.btn-ghost:hover {
  border-color: var(--ink);
}
/* On a cobalt or navy ground. */
.btn-ghost-inv {
  border-color: var(--hair-cobalt);
  color: var(--on-cobalt);
}
.btn-ghost-inv:hover {
  border-color: var(--on-cobalt);
}
.btn-danger {
  border-color: var(--bad);
  color: var(--bad);
}
.btn-danger:hover {
  background: var(--bad);
  color: var(--bone);
}
.btn-lg {
  font-size: 16px;
  padding: 14px 28px;
}
.btn-sm {
  font-size: 12.5px;
  padding: 6px 14px;
  border-width: 1px;
}
.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.45;
  pointer-events: none;
}

/* A button that reads as a link — for destructive actions inside a row, where
   a pill would shout. */
.linkish {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--cobalt);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.linkish-danger {
  color: var(--bad);
}

/* ===========================================================================
   Forms
   =========================================================================== */

.field {
  margin-bottom: var(--s3);
}
.field > label,
.field > .label {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: var(--s1);
}
.field .hint {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  color: var(--slate-2);
  max-width: 54ch;
}

input[type='text'],
input[type='email'],
input[type='password'],
input[type='url'],
input[type='number'],
input[type='date'],
input[type='time'],
input[type='datetime-local'],
input[type='search'],
select,
textarea {
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--edge);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  line-height: 1.4;
}
textarea {
  min-height: 140px;
  resize: vertical;
  font-family: var(--sans);
}
textarea.mono {
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.65;
}
input:focus,
select:focus,
textarea:focus {
  border-color: var(--cobalt);
}
input[aria-invalid='true'],
textarea[aria-invalid='true'] {
  border-color: var(--bad);
}
select {
  appearance: none;
  padding-right: 32px;
  /* Inline chevron, so no image request and no icon font. */
  background-image: linear-gradient(45deg, transparent 50%, var(--slate) 50%),
    linear-gradient(135deg, var(--slate) 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 14.5px;
}
.check input {
  margin-top: 3px;
  accent-color: var(--cobalt);
}

.field-row {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
  /* The children have no bottom margin of their own, so the row carries it —
     otherwise a field's hint text runs straight into the next label. */
  margin-bottom: var(--s3);
}
.field-row > .field {
  flex: 1 1 180px;
  margin-bottom: 0;
}

/* The error a form shows above itself when the server rejected it. */
.formerror {
  background: var(--bad-wash);
  border-left: 3px solid var(--bad);
  color: var(--bad);
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  margin-bottom: var(--s3);
  font-size: 14.5px;
}
.formerror ul {
  margin: 8px 0 0;
  padding-left: 18px;
}

/* ===========================================================================
   Auth — signup, login. Full-bleed cobalt, one card.
   =========================================================================== */

.auth {
  min-height: 100vh;
  background: var(--cobalt);
  color: var(--on-cobalt);
  display: grid;
  grid-template-columns: 1fr;
  align-content: start;
}
.auth-bar {
  padding: 22px var(--pad);
  display: flex;
  align-items: center;
  gap: var(--s2);
}
.auth-bar .wordmark {
  font-size: 24px;
  margin-right: auto;
  color: var(--on-cobalt);
}
.auth-bar a {
  color: var(--on-cobalt-dim);
  text-decoration: none;
  font-size: 14.5px;
}
.auth-bar a:hover {
  color: var(--on-cobalt);
}

.auth-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 440px);
  gap: clamp(32px, 6vw, 88px);
  align-items: center;
  padding: clamp(24px, 5vw, 64px) var(--pad) clamp(48px, 8vw, 96px);
  max-width: var(--max);
  margin: 0 auto;
  width: 100%;
}
.auth-pitch h1 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(40px, 6vw, 78px);
  line-height: 0.86;
  margin: 0 0 var(--s3);
  text-wrap: balance;
}
.auth-pitch h1 .co {
  color: var(--coral-display);
}
.auth-pitch .eyebrow {
  color: var(--coral-text);
}
.auth-pitch p {
  color: var(--on-cobalt-dim);
  max-width: 44ch;
  font-size: 17px;
}
.auth-pitch ul {
  list-style: none;
  margin: var(--s3) 0 0;
  padding: 0;
  max-width: 44ch;
}
.auth-pitch li {
  border-top: 1px solid var(--hair-cobalt);
  padding: 12px 0;
  color: var(--on-cobalt-dim);
  font-size: 15px;
}
.auth-pitch li b {
  color: var(--on-cobalt);
  font-weight: 600;
}

.auth-card {
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--radius);
  padding: clamp(28px, 3.4vw, 40px);
  box-shadow: 0 30px 70px -30px rgba(7, 11, 46, 0.6);
}
.auth-card h2 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 30px;
  line-height: 0.95;
  margin: 0 0 var(--s1);
}
.auth-card > p {
  margin: 0 0 var(--s3);
  color: var(--slate);
  font-size: 14.5px;
}
.auth-card .btn {
  width: 100%;
  text-align: center;
}
.auth-alt {
  margin: var(--s3) 0 0;
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--slate);
  text-align: center;
}

/* ===========================================================================
   App shell
   =========================================================================== */

.shell {
  display: grid;
  grid-template-columns: var(--sidebar) minmax(0, 1fr);
  min-height: 100vh;
}

.side {
  background: var(--navy);
  color: var(--on-cobalt);
  padding: 20px 0 24px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.side .wordmark {
  font-size: 22px;
  color: var(--on-cobalt);
  padding: 0 20px 20px;
  display: block;
}
.side nav {
  display: flex;
  flex-direction: column;
}
.side nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 20px;
  color: var(--on-cobalt-dim);
  text-decoration: none;
  font-size: 14.5px;
  border-left: 3px solid transparent;
}
.side nav a:hover {
  color: var(--on-cobalt);
  background: rgba(242, 239, 233, 0.05);
}
.side nav a[aria-current='page'] {
  color: var(--on-cobalt);
  border-left-color: var(--coral);
  background: rgba(242, 239, 233, 0.07);
  font-weight: 600;
}
.side h4 {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--c-com);
  margin: var(--s3) 0 8px;
  padding: 0 20px;
  font-weight: 500;
}
.side-foot {
  margin-top: auto;
  padding: var(--s2) 20px 0;
  border-top: 1px solid rgba(242, 239, 233, 0.12);
  font-size: 13px;
  color: var(--c-com);
}

/* The organisation switcher, at the top of the sidebar. */
.orgpick {
  margin: 0 12px var(--s2);
}
.orgpick summary {
  list-style: none;
  cursor: pointer;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: rgba(242, 239, 233, 0.07);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.orgpick summary::-webkit-details-marker {
  display: none;
}
.orgpick summary::after {
  content: '';
  margin-left: auto;
  border: 4px solid transparent;
  border-top-color: var(--on-cobalt-dim);
  margin-top: 4px;
}
.orgpick[open] summary::after {
  transform: rotate(180deg);
  margin-top: -4px;
}
.orgpick .orgname {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.orgpick form {
  margin: 6px 0 0;
}
.orgpick button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  color: var(--on-cobalt-dim);
  font: inherit;
  font-size: 13.5px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.orgpick button:hover {
  background: rgba(242, 239, 233, 0.08);
  color: var(--on-cobalt);
}

.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.topbar {
  height: var(--topbar);
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 0 var(--s3);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar h1 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 23px;
  line-height: 1;
  margin: 0;
}
.topbar .spacer {
  margin-left: auto;
}
.topbar form {
  display: inline;
}

.page {
  padding: var(--s3);
  flex: 1;
}
.page > section + section {
  margin-top: var(--s4);
}

.sechead {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  margin-bottom: var(--s2);
  flex-wrap: wrap;
}
.sechead h2 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 20px;
  line-height: 1;
  margin: 0;
}
.sechead .spacer {
  margin-left: auto;
}

/* ===========================================================================
   Panels and cards
   =========================================================================== */

.panel {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.panel-head {
  padding: 14px var(--s2);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
}
.panel-head .spacer {
  margin-left: auto;
}
.panel-body {
  padding: var(--s2);
}

.grid {
  display: grid;
  gap: var(--s2);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.grid-2 {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

/* The four numbers at the top of the dashboard. Narrower than the default grid
   track so all four sit on one row beside the sidebar at 1280px, which is the
   width most people actually have. */
.stats {
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.stat {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s2);
}
.stat b {
  font-family: var(--display);
  font-weight: 700;
  font-size: 40px;
  line-height: 0.85;
  display: block;
  font-variant-numeric: tabular-nums;
}
.stat span {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  display: block;
  margin-top: 10px;
}
.stat.alarm b {
  color: var(--bad);
}
.stat.alarm {
  border-color: var(--bad);
}

/* ===========================================================================
   State chips

   One per PostTarget state, plus the two that are COLUMNS rather than states —
   at-risk and verification-failed. Those are outlines rather than fills, because
   they qualify a state instead of replacing it: a post can be READY *and* at
   risk, and the chip pair has to be able to say so.
   =========================================================================== */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: 20px;
  white-space: nowrap;
  background: var(--idle-wash);
  color: var(--slate);
  border: 1px solid transparent;
}
.chip::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.chip-PENDING,
.chip-STAGING {
  background: var(--idle-wash);
  color: var(--slate);
}
.chip-READY,
.chip-PUBLISHING,
.chip-AWAITING_PLATFORM {
  background: var(--info-wash);
  color: var(--cobalt);
}
.chip-PUBLISHED {
  background: var(--ok-wash);
  color: var(--ok);
}
.chip-FAILED {
  background: var(--bad-wash);
  color: var(--bad);
}
.chip-CANCELED,
.chip-SKIPPED {
  background: transparent;
  color: var(--slate-2);
  border-color: var(--line-strong);
}
.chip-risk {
  background: transparent;
  color: var(--warn);
  border-color: var(--warn);
}
.chip-unverified {
  background: transparent;
  color: var(--bad);
  border-color: var(--bad);
}

/* PUBLISHING is the one state that is actively happening while you look at it. */
.chip-PUBLISHING::before {
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse {
  50% {
    opacity: 0.25;
  }
}

/* ===========================================================================
   Tables
   =========================================================================== */

.tablewrap {
  overflow-x: auto;
}
table {
  border-collapse: collapse;
  width: 100%;
  font-size: 14.5px;
}
caption {
  text-align: left;
  font-size: 13px;
  color: var(--slate);
  padding-bottom: 12px;
}
th {
  text-align: left;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--slate);
  padding: 0 14px 10px 0;
  border-bottom: 2px solid var(--line-strong);
  white-space: nowrap;
}
td {
  padding: 11px 14px 11px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
th:last-child,
td:last-child {
  padding-right: 0;
}
td.path {
  font-family: var(--mono);
  font-size: 13px;
  white-space: nowrap;
  color: var(--cobalt);
  font-weight: 500;
}
td.num,
th.num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
tr.rowlink:hover td {
  background: var(--bone);
}

/* ===========================================================================
   Calendar

   A month is a seven-column grid; a week is the same grid with taller cells.
   Both are plain CSS grid rather than a table, because the cells are drop
   targets and a <td> that is also a droppable is more fight than it is worth.
   =========================================================================== */

.cal {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--line);
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
}
.cal-dow {
  background: var(--paper);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  padding: 10px 10px;
  text-align: left;
}
.cal-day {
  background: #fff;
  min-height: 132px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.cal-day.outside {
  background: var(--paper);
}
.cal-day.outside .cal-date {
  color: var(--slate-2);
}
.cal-day.today {
  box-shadow: inset 0 3px 0 var(--coral);
}
.cal-date {
  font-family: var(--mono);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--slate);
  display: flex;
  align-items: center;
  gap: 6px;
}
.cal-day.today .cal-date {
  color: var(--coral);
  font-weight: 600;
}
.cal-date .add {
  margin-left: auto;
  opacity: 0;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--slate);
  font-size: 15px;
  line-height: 1;
  padding: 0 2px;
}
.cal-day:hover .add,
.add:focus-visible {
  opacity: 1;
}

/* One scheduled target. The left edge carries the state colour, so a month at
   a glance reads as a column of coloured ticks before you read any words. */
.ev {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--bone);
  border-left: 3px solid var(--slate-2);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 5px 7px;
  font-size: 12.5px;
  line-height: 1.3;
  overflow: hidden;
}
.ev:hover {
  background: var(--bone-2);
}
.ev .t {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--slate);
  font-variant-numeric: tabular-nums;
}
.ev .x {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ev .h {
  color: var(--slate-2);
  font-size: 11px;
}
.ev-READY,
.ev-PUBLISHING,
.ev-AWAITING_PLATFORM {
  border-left-color: var(--cobalt);
}
.ev-PUBLISHED {
  border-left-color: var(--ok);
}
.ev-FAILED {
  border-left-color: var(--bad);
}
.ev-CANCELED,
.ev-SKIPPED {
  border-left-color: var(--line-strong);
  opacity: 0.6;
}
.ev.risk {
  box-shadow: inset 0 0 0 1px var(--warn);
}
.ev .more {
  color: var(--slate);
  font-size: 11.5px;
}

.cal-nav {
  display: flex;
  align-items: center;
  gap: var(--s1);
  margin-bottom: var(--s2);
  flex-wrap: wrap;
}
.cal-nav h2 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 24px;
  line-height: 1;
  margin: 0 var(--s1) 0 0;
  min-width: 8ch;
}
.cal-nav .spacer {
  margin-left: auto;
}
.cal-nav .step {
  /* inline-grid + place-items, because these are anchors: a plain <a> sized to
     32px puts its glyph on a line box that does not centre and clips. */
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--edge);
  background: #fff;
  border-radius: var(--radius-sm);
  width: 32px;
  height: 32px;
  cursor: pointer;
  font: inherit;
  font-size: 18px;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
}
.cal-nav .step:hover {
  border-color: var(--ink);
}

/* A legend, because a colour with no key is decoration. */
.legend {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
  margin-top: var(--s2);
  font-size: 12px;
  color: var(--slate);
}
.legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.legend i {
  width: 10px;
  height: 3px;
  border-radius: 2px;
  background: currentColor;
}

/* ===========================================================================
   Post detail
   =========================================================================== */

.item + .item {
  border-top: 1px solid var(--line);
  margin-top: var(--s2);
  padding-top: var(--s2);
}
.item p {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* A thread is numbered rather than indented: indentation implies a reply to the
   reader, and these are all one author's parts of one post. */
.item-n {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--bone-2);
  color: var(--slate);
  font-family: var(--mono);
  font-size: 11px;
  margin-bottom: 6px;
}

/*
   The four moments. A grid rather than a list of sentences, so the times line
   up in a column and a skew is legible at a glance instead of having to be read.
*/
.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.tl {
  background: #fff;
  display: grid;
  grid-template-columns: 92px 150px minmax(0, 1fr);
  gap: var(--s2);
  align-items: baseline;
  padding: 9px 12px;
  font-size: 13px;
}
.tl.pending {
  background: var(--paper);
}
.tl-k {
  font-size: 11px;
  color: var(--slate-2);
  letter-spacing: 0.04em;
}
.tl-v {
  font-weight: 600;
}
.tl.pending .tl-v {
  color: var(--slate-2);
  font-weight: 400;
}
.tl-n {
  color: var(--slate);
}
.ok-text {
  color: var(--ok);
}
.bad-text {
  color: var(--bad);
}

@media (max-width: 620px) {
  .tl {
    grid-template-columns: 1fr;
    gap: 2px;
  }
}

/* ===========================================================================
   Channels
   =========================================================================== */

.chan {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s2);
}
.chan .avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--bone-2);
  object-fit: cover;
  flex: none;
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 17px;
  color: var(--slate);
  text-transform: uppercase;
}
.chan .who {
  min-width: 0;
  flex: 1;
}
.chan .handle {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chan .prov {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate-2);
}
.chan .acts {
  display: flex;
  gap: var(--s1);
  flex-wrap: wrap;
  margin-top: 10px;
}
.chan.needs {
  border-color: var(--warn);
  background: var(--warn-wash);
}

/* ===========================================================================
   Notices — the needs-attention surface
   =========================================================================== */

.notice {
  border-left: 3px solid var(--slate-2);
  background: #fff;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 12px var(--s2);
  display: flex;
  gap: var(--s2);
  align-items: flex-start;
}
.notice + .notice {
  margin-top: var(--s1);
}
.notice .body {
  flex: 1;
  min-width: 0;
}
.notice strong {
  display: block;
  font-size: 14.5px;
}
.notice p {
  margin: 3px 0 0;
  font-size: 13.5px;
  color: var(--slate);
}
.notice-warn {
  border-left-color: var(--warn);
  background: var(--warn-wash);
}
.notice-bad {
  border-left-color: var(--bad);
  background: var(--bad-wash);
}
.notice-ok {
  border-left-color: var(--ok);
  background: var(--ok-wash);
}

/* The banner that says "nothing here yet", with the one thing to do next. */
.empty {
  text-align: center;
  padding: var(--s4) var(--s2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--slate);
}
.empty h3 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 22px;
  margin: 0 0 8px;
  color: var(--ink);
}
.empty p {
  margin: 0 auto var(--s2);
  max-width: 46ch;
  font-size: 14.5px;
}

/* ===========================================================================
   Code — reused verbatim from the landing page, so a snippet in the docs and a
   snippet in the console are the same object.
   =========================================================================== */

.code {
  background: var(--navy);
  border-radius: 12px;
  overflow: hidden;
}
.code-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;
  border-bottom: 1px solid rgba(242, 239, 233, 0.1);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-com);
  flex-wrap: wrap;
}
.code-head .verb {
  color: var(--c-verb);
  font-weight: 600;
}
.code-head .path {
  color: var(--on-cobalt);
  letter-spacing: 0.02em;
  text-transform: none;
  font-size: 13px;
}
.code-head .tail {
  margin-left: auto;
}
.code pre {
  margin: 0;
  padding: 20px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.72;
  color: var(--on-cobalt);
  tab-size: 2;
}
.code code {
  font: inherit;
}
.k {
  color: var(--c-key);
}
.s {
  color: var(--c-str);
}
.n {
  color: var(--c-num);
}
.cm {
  color: var(--c-com);
}
.vb {
  color: var(--c-verb);
  font-weight: 600;
}
.ok-t {
  color: var(--c-ok);
}

/* A secret shown once. */
.reveal {
  font-family: var(--mono);
  font-size: 13.5px;
  background: var(--navy);
  color: var(--c-str);
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  overflow-wrap: anywhere;
  user-select: all;
}

/* ===========================================================================
   Responsive
   =========================================================================== */

@media (max-width: 900px) {
  .auth-body {
    grid-template-columns: 1fr;
  }
  .auth-pitch {
    order: 2;
  }
}

@media (max-width: 820px) {
  .shell {
    grid-template-columns: 1fr;
  }
  .side {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: var(--s1);
    padding: 10px var(--s2);
    overflow-x: auto;
  }
  .side .wordmark {
    padding: 0 var(--s2) 0 0;
  }
  .side nav {
    flex-direction: row;
  }
  .side nav a {
    border-left: 0;
    border-bottom: 3px solid transparent;
    padding: 6px 10px;
    white-space: nowrap;
  }
  .side nav a[aria-current='page'] {
    border-left: 0;
    border-bottom-color: var(--coral);
  }
  .side h4,
  .side-foot,
  .orgpick {
    display: none;
  }
  .page {
    padding: var(--s2);
  }

  /* A seven-column month on a phone is seven columns of nothing. Stack the
     days into a list and let the date carry the structure. */
  .cal {
    grid-template-columns: 1fr;
  }
  .cal-dow {
    display: none;
  }
  .cal-day {
    min-height: 0;
  }
  .cal-day.outside:empty,
  .cal-day.outside {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

@media print {
  .side,
  .topbar,
  .cal-nav,
  .btn {
    display: none;
  }
  .shell {
    grid-template-columns: 1fr;
  }
}

/* ===========================================================================
   Legal documents

   Long-form reading on a bone ground: one column at a comfortable measure, a
   sticky contents rail on wide screens, and nothing else. These pages are read
   once by a person and repeatedly by a platform reviewer, and both want the
   same thing — to find a clause and be sure of it.
   =========================================================================== */

.doc {
  background: var(--bone);
}

.doc-bar {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex-wrap: wrap;
  padding: 20px var(--pad);
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.doc-bar .wordmark {
  font-size: 22px;
  color: var(--ink);
  margin-right: auto;
}
.doc-bar nav {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
}
.doc-bar nav a {
  font-size: 13.5px;
  text-decoration: none;
  color: var(--slate);
}
.doc-bar nav a:hover {
  color: var(--ink);
}
.doc-bar nav a[aria-current='page'] {
  color: var(--ink);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--coral);
}

/* Impossible to miss, deliberately. */
.doc-draft {
  background: var(--warn-wash);
  border-bottom: 3px solid var(--warn);
  color: var(--warn);
  padding: 14px var(--pad);
}
.doc-draft strong {
  font-family: var(--display);
  text-transform: uppercase;
  font-size: 18px;
  letter-spacing: 0.01em;
}
.doc-draft p {
  margin: 4px 0 0;
  font-size: 13.5px;
  max-width: 90ch;
}
.doc-draft code {
  font-family: var(--mono);
  font-size: 12px;
  background: rgba(138, 82, 0, 0.12);
  padding: 1px 5px;
  border-radius: 3px;
}

.doc-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(28px, 4vw, 56px) var(--pad) var(--s4);
}
@media (min-width: 1000px) {
  .doc-body {
    grid-template-columns: 230px minmax(0, 1fr);
  }
}

.doc-toc {
  align-self: start;
}
@media (min-width: 1000px) {
  .doc-toc {
    position: sticky;
    top: 24px;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
  }
}
.doc-toc h2 {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--slate-2);
  margin: 0 0 10px;
  font-weight: 500;
}
.doc-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: toc;
}
.doc-toc li {
  margin-bottom: 6px;
}
.doc-toc a {
  text-decoration: none;
  color: var(--slate);
  font-size: 13.5px;
  line-height: 1.35;
  display: block;
}
.doc-toc a:hover {
  color: var(--cobalt);
}

/* 68 characters. Legal prose is read slowly, and a long measure is where the
   eye loses the line. */
.doc-main {
  max-width: 68ch;
  font-size: 16.5px;
  line-height: 1.65;
}
.doc-main h1 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(34px, 5vw, 54px);
  line-height: 0.95;
  margin: 0 0 var(--s3);
  text-wrap: balance;
}
.doc-main h2 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 24px;
  line-height: 1.05;
  margin: var(--s4) 0 var(--s2);
  padding-top: var(--s2);
  border-top: 2px solid var(--line-strong);
  text-wrap: balance;
}
.doc-main h3 {
  font-size: 17px;
  font-weight: 700;
  margin: var(--s3) 0 var(--s1);
}
.doc-main h4 {
  font-size: 15.5px;
  font-weight: 600;
  margin: var(--s2) 0 var(--s1);
  color: var(--slate);
}
.doc-main p {
  margin: 0 0 var(--s2);
}
.doc-main ul,
.doc-main ol {
  margin: 0 0 var(--s2);
  padding-left: 24px;
}
.doc-main li {
  margin-bottom: 7px;
}
.doc-main hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: var(--s3) 0;
}
.doc-main blockquote {
  margin: 0 0 var(--s2);
  padding: 12px 18px;
  border-left: 3px solid var(--cobalt);
  background: var(--paper);
  font-size: 15.5px;
}
.doc-main code {
  font-family: var(--mono);
  font-size: 14px;
  background: var(--bone-2);
  padding: 1px 5px;
  border-radius: 4px;
  overflow-wrap: anywhere;
}
.doc-pre {
  background: var(--navy);
  color: var(--on-cobalt);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
  padding: 16px 18px;
  border-radius: var(--radius-sm);
  overflow-x: auto;
  margin: 0 0 var(--s2);
}
.doc-pre code {
  background: none;
  color: inherit;
  padding: 0;
  font-size: inherit;
}
.doc-main table {
  min-width: 0;
  font-size: 14.5px;
  margin-bottom: var(--s2);
}
/* An anchored heading must not land under the sticky nav. */
.doc-main :target {
  scroll-margin-top: 20px;
}

.doc-foot {
  border-top: 1px solid var(--line);
  background: var(--paper);
  padding: var(--s3) var(--pad);
  font-size: 13.5px;
}
.doc-foot p {
  max-width: var(--max);
  margin: 0 auto;
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
  color: var(--slate);
}

/* ===========================================================================
   The confirm page

   One screen, arrived at from a chat client, read once and acted on. Narrow,
   quiet, and with the platform-required text given as much room as the content
   — because on three of the five platforms that text is the reason the screen
   exists.
   =========================================================================== */

.confirm-page {
  background: var(--bone);
}
.confirm {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(28px, 5vw, 56px) var(--pad) var(--s4);
}
.confirm-head {
  margin-bottom: var(--s3);
}
.confirm-head h1 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(34px, 6vw, 56px);
  line-height: 0.95;
  margin: 8px 0 12px;
}
.confirm-head .eyebrow {
  color: var(--coral-text);
  margin: 0;
}

.confirm-targets {
  list-style: none;
  margin: 0;
  padding: 0;
}
.confirm-targets li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  flex-wrap: wrap;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.confirm-targets li:last-child {
  border-bottom: 0;
}
.confirm-targets .who {
  font-weight: 600;
}
.confirm-targets .prov {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate-2);
}
.confirm-targets .when {
  margin-left: auto;
  color: var(--slate);
  font-size: 14px;
}

/* Bordered in coral: this block is the compliance surface, and it should not
   look like a footnote. */
.confirm-required {
  border-color: var(--coral);
}
.confirm-required .panel-head {
  color: var(--coral-text);
  border-bottom-color: var(--coral);
}
.disclosure + .disclosure {
  margin-top: var(--s3);
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
}
.disclosure h3 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 17px;
  margin: 0 0 8px;
}
.disclosure .decl {
  margin: 0 0 8px;
  font-size: 14.5px;
  color: var(--ink);
}

.commercial {
  margin-top: var(--s2);
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
}
.commercial-options {
  display: grid;
  gap: 8px;
  margin: 10px 0 0 26px;
}
.commercial .hint,
.commercial-options .hint {
  display: block;
  font-size: 13px;
  color: var(--slate);
  margin-top: 2px;
}

.confirm-actions {
  display: grid;
  gap: var(--s2);
  margin-top: var(--s3);
}
.confirm-actions .row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.confirm-done {
  max-width: 620px;
  margin: clamp(40px, 8vw, 90px) auto;
  padding: clamp(28px, 4vw, 44px);
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--ok);
  border-radius: var(--radius);
}
.confirm-done.no {
  border-left-color: var(--slate-2);
}
.confirm-done h2 {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 30px;
  margin: 0 0 10px;
  color: var(--ok);
}
.confirm-done.no h2 {
  color: var(--slate);
}
.confirm-done p {
  margin: 0;
  color: var(--slate);
}

/* ===========================================================================
   Bulk import
   =========================================================================== */

.dropzone {
  border: 2px dashed var(--edge);
  border-radius: var(--radius);
  padding: clamp(28px, 5vw, 48px) var(--s3);
  text-align: center;
  background: var(--card);
}
.dropzone.over {
  border-color: var(--cobalt);
  background: var(--info-wash);
}
.dropzone p {
  margin: 0 0 6px;
}
.dropzone p:last-child {
  margin-bottom: 0;
  font-size: 14px;
}

.filelist {
  list-style: none;
  margin: var(--s2) 0 0;
  padding: 0;
}
.fileitem {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  align-items: baseline;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.fileitem .n {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fileitem .s {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--slate-2);
  font-variant-numeric: tabular-nums;
}
/* The sheet is the one file that is not a video; it reads differently. */
.fileitem.sheet .n::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  background: var(--coral);
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: middle;
}
.fileitem .p {
  grid-column: 1 / -1;
  height: 3px;
  background: var(--bone-2);
  border-radius: 2px;
  overflow: hidden;
}
.fileitem .p i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--cobalt);
  transition: width 0.2s linear;
}

/* A blocked row has to be findable in a table of two hundred. */
tr.row-blocked td {
  background: var(--bad-wash);
}
.rowproblem {
  font-size: 13px;
  color: var(--bad);
  margin-bottom: 3px;
}
.rowproblem.warn {
  color: var(--warn);
}
.rowproblem b {
  font-family: var(--mono);
  font-size: 11.5px;
}

/* What each role can actually do, next to the picker rather than in a doc. */
.rolekey {
  list-style: none;
  margin: var(--s2) 0 0;
  padding: 0;
  max-width: 760px;
  font-size: 13.5px;
  color: var(--slate);
}
.rolekey li {
  padding: 6px 0;
  border-top: 1px solid var(--line);
}
.rolekey b {
  color: var(--ink);
  display: inline-block;
  min-width: 68px;
}

/* ===========================================================================
   Media library

   A grid, not a table: the question is "which one was it", and that is answered
   by looking. Only the metadata somebody acts on — ready, in use — is on the
   tile; the rest is available by opening it.
   =========================================================================== */

.medialib {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s2);
}
.tile {
  margin: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.tile.pending {
  border-style: dashed;
}
.tile .thumb {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--bone-2);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.tile .thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.tile .kind {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate-2);
}
.tile .badge {
  position: absolute;
  top: 8px;
  left: 8px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: var(--warn-wash);
  color: var(--warn);
  padding: 3px 7px;
  border-radius: 20px;
}
.tile figcaption {
  padding: 10px 12px 12px;
  display: grid;
  gap: 3px;
  font-size: 13px;
  min-width: 0;
}
.tile figcaption b {
  font-size: 13.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tile .meta {
  color: var(--slate-2);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}
.tile .alt {
  color: var(--slate);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tile .acts {
  display: flex;
  gap: 10px;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.tile .used {
  font-size: 11.5px;
  color: var(--cobalt);
}
.tile .used.none {
  color: var(--slate-2);
}
.tile .id {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--slate-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: all;
}

/* ===========================================================================
   The composer's media picker
   ---------------------------------------------------------------------------
   Smaller than the library's tiles on purpose: the question here is "which one
   was it", asked while writing, so the grid has to be scannable without pushing
   the text box off the screen.
   =========================================================================== */

.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  max-height: 340px;
  overflow-y: auto;
  padding: 2px;
}
.media-pick {
  position: relative;
  display: grid;
  gap: 4px;
  cursor: pointer;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--card);
}
/* The checkbox stays in the layout for keyboard and screen readers; the tile
   around it is what carries the selected state visually. */
.media-pick input {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 1;
  margin: 0;
}
.media-pick img,
.media-pick .media-kind {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  display: grid;
  place-items: center;
  background: var(--bone-2);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--slate-2);
}
.media-pick .media-name {
  padding: 0 7px 7px;
  font-size: 11px;
  color: var(--slate);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.media-pick:focus-within {
  outline: 2px solid var(--cobalt);
  outline-offset: 1px;
}
.media-pick:has(input:checked) {
  border-color: var(--cobalt);
  box-shadow: inset 0 0 0 1px var(--cobalt);
}

/* A <summary> that opens something optional.
   Its own class rather than `.hint`, which sets display:block — and a summary
   that is display:block loses its disclosure triangle, so the control stops
   looking like a control while still behaving like one. */
.disclose {
  cursor: pointer;
  font-size: 12.5px;
  color: var(--slate);
  padding: 2px 0;
}
.disclose:hover {
  color: var(--cobalt);
}
.disclose::marker {
  color: var(--slate-2);
}

/* Validation feedback rendered beside the account that raised it. */
.hint.ok {
  color: var(--ok);
}
.hint.bad {
  color: var(--bad);
}

/* ===========================================================================
   Week and day: a time grid
   ---------------------------------------------------------------------------
   The month grid answers "what is going out this month". This answers "am I
   posting three things at nine on Tuesday", which needs vertical distance to
   mean something — so events are positioned by minute rather than stacked.
   =========================================================================== */

.tgrid {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper);
}
.tgrid-head,
.tgrid-body {
  display: grid;
  /* The gutter is fixed so hour labels line up with the rules beside them. */
  grid-template-columns: 56px repeat(var(--cols, 7), minmax(0, 1fr));
}
.tgrid-head {
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 2;
}
.tgrid-col-head {
  padding: 9px 10px;
  border-left: 1px solid var(--line);
  display: flex;
  align-items: baseline;
  gap: 7px;
}
.tgrid-col-head .dow {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
}
.tgrid-col-head .dom {
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.tgrid-col-head.today .dom {
  color: var(--cobalt);
}

.tgrid-body {
  /* One hour is 52px. Tall enough for a two-line event, short enough that a
     working day fits without scrolling on a laptop. */
  height: calc(var(--rows, 15) * 52px);
  position: relative;
}
.tgrid-gutter {
  position: relative;
}
.tgrid-hour {
  height: 52px;
  position: relative;
}
.tgrid-hour span {
  position: absolute;
  top: -0.6em;
  right: 8px;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--slate-2);
  font-variant-numeric: tabular-nums;
}
/* The first label would sit above the grid and disappear under the sticky
   header, so it hangs below its own rule instead of straddling it. */
.tgrid-hour:first-child span {
  top: 3px;
}
.tgrid-col {
  position: relative;
  border-left: 1px solid var(--line);
}
.tgrid-col.today {
  background: var(--bone);
}
.tgrid-slot {
  height: 52px;
  border-bottom: 1px solid var(--line);
}
.tgrid-slot:last-of-type {
  border-bottom: 0;
}

.tgrid-ev {
  position: absolute;
  z-index: 1;
  /* A hairline of gutter so two side-by-side events never touch. */
  margin: 0 2px 0 0;
  box-sizing: border-box;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--card);
  box-shadow: var(--shadow);
  min-height: 26px;
}
.tgrid-ev:hover {
  z-index: 3;
  background: var(--bone-2);
}

/* Where "now" is, so nobody has to read the clock and subtract. */
.tgrid-now {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1.5px solid var(--coral);
  z-index: 2;
  pointer-events: none;
}
.tgrid-now::before {
  content: '';
  position: absolute;
  left: -3px;
  top: -3.5px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--coral);
}

.tgrid-add {
  position: absolute;
  right: 6px;
  bottom: 6px;
  z-index: 2;
  width: 24px;
  height: 24px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--edge);
  background: var(--paper);
  color: var(--slate);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.12s;
}
.tgrid-col:hover .tgrid-add,
.tgrid-add:focus-visible {
  opacity: 1;
}

.viewswitch {
  display: inline-flex;
  border: 1px solid var(--edge);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.viewswitch .vs {
  padding: 5px 12px;
  font-size: 12.5px;
  text-transform: capitalize;
  text-decoration: none;
  color: var(--slate);
  border-left: 1px solid var(--edge);
}
.viewswitch .vs:first-child {
  border-left: 0;
}
.viewswitch .vs.on {
  background: var(--ink);
  color: var(--paper);
}

@media (max-width: 720px) {
  /* Seven columns of 40px is not a week, it is a smear. Scroll it instead. */
  .tgrid {
    overflow-x: auto;
  }
  .tgrid-head,
  .tgrid-body {
    min-width: 620px;
  }
}

/* The composer's repeat block. */
.repeat-days {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 4px;
}
.repeat-days-label {
  /* Its own row above the pills, which a flex child otherwise never gets. */
  flex-basis: 100%;
  font-size: 12.5px;
  color: var(--slate);
  margin-bottom: 2px;
}
.daypick {
  position: relative;
  cursor: pointer;
}
.daypick input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}
.daypick span {
  display: inline-grid;
  place-items: center;
  min-width: 42px;
  padding: 6px 8px;
  border: 1px solid var(--edge);
  border-radius: var(--radius-sm);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate);
}
.daypick:has(input:checked) span {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
.daypick:focus-within span {
  outline: 2px solid var(--cobalt);
  outline-offset: 1px;
}

/* One occurrence of many, said on the post it belongs to. */
.seriesnote {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px;
  margin-bottom: var(--s2);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--bone);
  font-size: 13px;
}
.seriesnote .which {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
}

/* ===========================================================================
   Security: the second factor, and every browser signed in
   =========================================================================== */

.qr-wrap {
  display: inline-block;
  padding: 10px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.qr {
  display: block;
  width: 180px;
  height: 180px;
}

.codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 8px;
  margin-top: 12px;
}
.codes code {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  padding: 7px 10px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  text-align: center;
  /* One click selects a whole code, because these get copied one at a time. */
  user-select: all;
}

.sessionrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.sessionrow:last-of-type {
  border-bottom: 0;
}
.sessionrow .meta {
  color: var(--slate-2);
  font-size: 12.5px;
  margin-top: 2px;
}
.sessionrow.current {
  /* Marked rather than hidden: "sign out everywhere else" is only a safe
     button if you can see which one is you. */
  border-left: 3px solid var(--cobalt);
  padding-left: 10px;
  margin-left: -13px;
}

/* What the platform says, on the post it is about. */
.numbers {
  display: flex;
  align-items: baseline;
  gap: 26px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.num {
  display: grid;
  gap: 1px;
}
.num b {
  font-size: 21px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.num span {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate-2);
}
.num-when {
  /* Never omitted: an impression count with no timestamp is a number somebody
     will assume is live. */
  margin-left: auto;
  font-size: 12px;
  color: var(--slate-2);
}

/* ===========================================================================
   The status page
   ---------------------------------------------------------------------------
   Deliberately flat. Every number is computed from the rows the scheduler
   writes, so the page says what happened rather than reassuring anybody.
   =========================================================================== */

.status {
  max-width: 760px;
  margin: 0 auto;
  padding: var(--s4) var(--s3) 72px;
}
.status h1 {
  font-family: var(--display);
  text-transform: uppercase;
  font-size: 34px;
  margin: 0 0 var(--s3);
}
.status h2 {
  font-size: 15px;
  font-family: var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  margin: var(--s4) 0 var(--s1);
}
.status section {
  border-top: 1px solid var(--line);
}

.status-headline {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
}
.status-headline b {
  font-size: 18px;
}
.status-headline p {
  margin: 2px 0 0;
  color: var(--slate);
}
.status-headline .dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-top: 5px;
  flex: none;
  background: var(--idle);
}
.status-headline.operational .dot,
.status-dot.operational {
  background: var(--ok);
}
.status-headline.degraded .dot,
.status-dot.degraded {
  background: var(--warn);
}
.status-headline.down .dot,
.status-dot.down {
  background: var(--bad);
}

.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 7px;
  background: var(--idle);
}

.status-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--s2);
}
.status-table th,
.status-table td {
  text-align: left;
  padding: 12px 10px 12px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  font-weight: 400;
}
.status-table thead th {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate-2);
}
.status-table tbody th {
  font-weight: 600;
}
.status-table td p {
  margin: 4px 0 0;
  font-size: 12.5px;
  max-width: 44ch;
}
.status-table .tabular {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.status-foot {
  margin-top: var(--s4);
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--slate);
}

/* The support screen. Dense on purpose: it is read during a phone call. */
.admin-search {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: var(--s3);
}
.admin-search .field {
  flex: 1;
  max-width: 520px;
  margin: 0;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
}
.admin-table th,
.admin-table td {
  text-align: left;
  padding: 11px 12px 11px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  font-weight: 400;
  font-size: 13.5px;
}
.admin-table thead th {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate-2);
}
.admin-table tbody th {
  font-weight: 600;
}
.admin-table .meta {
  color: var(--slate-2);
  font-size: 11.5px;
  margin-top: 2px;
}
.admin-table .tabular {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
