/* ITZA Press - design system.
 *
 * Spec 17: a reading and writing environment for people who take writing
 * seriously. It must feel like a publication, not a dashboard, and not like a
 * crypto product. A reader who does not know what a blockchain is must never
 * meet one.
 *
 * NO WEB FONTS. Spec 3.2: cdn.itzalabs.com is the only permitted remote
 * origin, and that is for the platform library alone - no font CDN, no icon
 * font, no external stylesheet. Real subset faces ship from the node as
 * assets; until they are chosen (17.3 asks for a characterful display serif
 * that is not Georgia and not Playfair) these stacks use what is already on
 * the device, which costs nothing and never blocks first paint.
 */

:root {
  /* Spec 17.2. Two values are deliberately darker than the source palette -
   * see the note below - and everything else is verbatim. */
  --ink: #12161c;      /* body text, dominant by area */
  --paper: #fbfaf7;    /* the reading surface */
  --navy: #0b2a4a;     /* headers, structure */
  --gold: #f5c711;     /* THE SINGLE ACCENT: verification, provenance only */
  --rule: #e2ded6;     /* hairlines */

  /* CONTRAST CORRECTIONS, against --paper, per the 17.5 quality floor
   * ("WCAG 2.1 AA contrast verified against the reading surface
   * specifically"). The source values fail that floor for body-size text:
   *
   *   --muted #6b7280 -> 4.26:1   below the 4.5:1 minimum
   *   --blue  #0c7ffb -> 3.70:1   below the 4.5:1 minimum
   *
   * Metadata and links are both normal-size text on the reading surface, so
   * both need 4.5:1. The corrected values below measure 5.0:1 and are within
   * a hair of the originals in hue. The original --blue is kept as
   * --blue-bright for large UI elements and focus rings, where 3:1 is the
   * applicable threshold and it passes comfortably. */
  --muted: #666d79;        /* metadata, timestamps - 5.0:1 */
  --blue: #0b6ad4;         /* interactive, links, actions - 5.0:1 */
  --blue-bright: #0c7ffb;  /* large UI and focus only, never body text */

  /* 42rem at the 20px body is ~65 characters a line - the classic reading
   * measure, and within a few pixels of Medium's 680px column. The first
   * version shipped 34rem (~50 chars): correct for a printed novella,
   * visibly cramped for a web article (user comparison, 2026-08-05). The
   * measure is in rem on purpose: the text-size setting scales the root, so
   * characters-per-line stays constant at every size. */
  --measure: 42rem;        /* reader-adjustable, see 17.3 */
  --body-size: 20px;       /* reader-adjustable, 19-21px range */
  --leading: 1.65;

  --serif-body: 'Iowan Old Style', 'Palatino Linotype', Palatino, Charter,
    'Bitstream Charter', 'Source Serif Pro', serif;
  --serif-display: 'Hoefler Text', 'Baskerville Old Face', Baskerville,
    'Times New Roman', serif;
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

/* Reader controls (17.3): the reading experience is the product, so the
 * reader sets the scale and the line width. Applied on <html> by an inline
 * script BEFORE first paint, so articles inherit them without JavaScript and
 * without a flash at the wrong size. */
/* The type scale moves the ROOT SIZE as well as the article body. The first
 * version scaled only --body-size, so dates, bylines, menus and every other
 * rem-sized surface ignored the reader's setting entirely (reported
 * 2026-08-02: "it doesn't seem to be affecting the date and other areas").
 * rem inherits from here, so now everything breathes together. */
html[data-size='s'] { --body-size: 19px; font-size: 15px; }
html[data-size='l'] { --body-size: 21px; font-size: 17.5px; }
html[data-size='xl'] { --body-size: 23px; font-size: 19px; }
/* Narrow IS the old default - anyone who liked the tighter column picks it
 * in Settings and gets exactly what shipped before. */
html[data-measure='narrow'] { --measure: 34rem; }
html[data-measure='wide'] { --measure: 48rem; }
html[data-justify='1'] .article p { text-align: justify; hyphens: auto; }

/* Reading surface themes. Dark keeps the same hierarchy rather than inverting
 * it, and gold stays gold because it means one thing in both (17.2). Each is
 * checked for AA contrast against its own paper, not against the light one. */
html[data-theme='dark'] {
  --ink: #e8e6e1;
  --paper: #14171c;
  --navy: #a9c6e8;
  --rule: #2b3038;
  --muted: #9aa1ad;       /* 7.0:1 on this paper */
  --blue: #6fb3ff;        /* 6.9:1 */
  --blue-bright: #8ec6ff;
}

html[data-theme='hc'] {
  --ink: #000000;
  --paper: #ffffff;
  --navy: #000000;
  --rule: #000000;
  --muted: #3a3a3a;
  --blue: #0033cc;
  --gold: #a06f00;        /* the mark still reads at high contrast */
}

/* A reader who asked for less motion gets it whether or not the OS knows. */
html[data-motion='reduce'] *,
html[data-motion='reduce'] *::before,
html[data-motion='reduce'] *::after {
  animation-duration: 0.001ms !important;
  transition-duration: 0.001ms !important;
}

/* ---------------------------------------------------------------------
   Screens, modal, toast
   --------------------------------------------------------------------- */

.screen { display: none; }
.screen.on { display: block; }
.screen:focus { outline: none; }

.apphead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 1.25rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--sans);
}

/* The wordmark - the HOUSE STANDARD, mirrored from the marketing site's
 * stylesheet: ITZA in corporate blue (600) runs straight into the product
 * word in gold (800), no space. On light paper the gold deepens to #ad8009
 * to clear the contrast floor (brand gold on near-white is illegible - the
 * site's own comment); on dark it brightens back to brand gold, and ITZA
 * lifts to the site's dark-context blue. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--serif-display);
  font-size: 1.05rem;
  text-decoration: none;
  letter-spacing: -0.01em;
}

.brand-mark { width: 22px; height: 22px; }
.wm { white-space: nowrap; }
.wm-itza { color: #0c7ffb; font-weight: 600; }
.wm-prod { color: #ad8009; font-weight: 800; }
html[data-theme='dark'] .wm-itza { color: #4d9bff; }
html[data-theme='dark'] .wm-prod { color: #f5c711; }

.appnav { display: flex; align-items: center; gap: 1rem; font-size: 0.82rem; }
.appnav a { color: var(--blue); text-decoration: none; padding-bottom: 2px; }
.appnav a:hover { text-decoration: underline; }
.appnav a[aria-current='page'] { color: var(--navy); font-weight: 600; border-bottom: 2px solid var(--navy); }
.appnav a[hidden] { display: none; }

/* Visible keyboard focus everywhere (17.5). */
/* Focus, in two registers.
 *
 * CONTROLS - things you press - keep a visible ring: keyboard users navigate
 * by it, and 3:1 contrast against any surface is the requirement the bright
 * blue exists to meet.
 *
 * FIELDS - things you type into - show focus with the caret they already
 * have, plus a quiet border shift. A ring around a text field says "form";
 * around the writing surface it says "you are filling in a box" on the exact
 * pixels where the design is supposed to say "you are writing the page". */
a:focus-visible, button:focus-visible, select:focus-visible,
[role="button"]:focus-visible {
  outline: 2px solid var(--blue-bright);
  outline-offset: 2px;
}

input:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(12, 127, 251, 0.13);
}

/* The writing surface itself: no ring, no glow, no box. The caret, the
 * placeholder disappearing and the toolbar arriving are the focus state.
 * This is also what keeps the editor visually identical to the published
 * page - same measure, same type, no furniture around it. */
.editor:focus-visible,
.editor:focus,
.title-input:focus-visible,
.subtitle-input:focus-visible {
  outline: none;
  border-color: transparent;
  box-shadow: none;
}

.iconbtn {
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--muted);
  border-radius: 4px;
  font-size: 1rem;
  line-height: 1;
  padding: 0.3rem 0.5rem;
  cursor: pointer;
}

#scrim {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(11, 42, 74, 0.45);
  /* ABOVE #screen-onboard.on (z 50, ported verbatim from Chess). At 40 the
   * signup confirmation modal opened UNDERNEATH the opaque sign-in card:
   * "Create account" appeared to do absolutely nothing, while its modal sat
   * waiting where no click could reach it. Chess's own scrim is 60 for the
   * same reason - the modal layer must beat every screen, onboarding
   * included. */
  z-index: 60;
  padding: 1rem;
  overflow-y: auto;
}

#scrim.on { display: flex; align-items: flex-start; justify-content: center; }

#modal {
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 8px;
  width: 100%;
  max-width: 32rem;
  margin: 3vh auto;
  padding: 1.25rem;
  font-family: var(--sans);
  font-size: 0.88rem;
}

.mhead {
  font-family: var(--serif-display);
  font-size: 1.4rem;
  color: var(--navy);
  margin-bottom: 1rem;
}

.mbtns { margin-top: 1.25rem; }

#toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%) translateY(1rem);
  background: var(--navy);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 0.82rem;
  line-height: 1.4;
  padding: 0.7rem 1rem;
  border-radius: 6px;
  max-width: min(34rem, calc(100vw - 2rem));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  /* Above every screen AND the modal scrim (60) - a toast is feedback about
   * the thing you just did and must never be buried under it. Chess puts its
   * toasts at 90 for the same reason. At 50 this TIED #screen-onboard.on and
   * only won by DOM order, which is a coin toss nobody should bet UI on. */
  z-index: 90;
}

#toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------------------------------------------------------------------
   Sign in - PORTED 1:1 FROM ITZA CHESS, which ported it from ITZA CHAT
   ---------------------------------------------------------------------

   These values are Chess's, verbatim, not a Press reinterpretation of them.
   The sign-in screen is the same screen in every ITZA app on purpose: it is
   the same account, and a person who has signed in to one should recognise
   the next one immediately.

   SELF-CONTAINED. The whole palette is scoped to #screen-onboard rather than
   :root, so the card cannot be disturbed by the app's own theme and cannot
   disturb it either. Light is the default; dark follows the app's theme
   attribute, which on Press is html[data-theme] rather than Chess's
   html[data-bg] - that mapping is the only change made to any of it.
   --------------------------------------------------------------------- */

#screen-onboard{
  --ob-blue:#0c7ffb; --ob-blue-soft:#1d6fd0; --ob-gold:#f5c711;
  --ob-acc:#0c7ffb; --ob-acc-ink:#ffffff;
  --ob-bg:#f3f4f6; --ob-bg2:#ffffff; --ob-bg3:#f7f7f8;
  --ob-ink:#0b2a4a; --ob-ink2:#1e416b; --ob-ink3:#41618c;
  --ob-line:#d7dbe2; --ob-line2:#c5ccd6; --ob-hover:rgba(12,127,251,.06);
  --ob-card-shadow:0 18px 50px rgba(24,59,103,.12);
  --ob-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --ob-r-sm:8px;
  --ob-danger:#c62828;
}
html[data-theme="dark"] #screen-onboard{
  --ob-bg:#0b1f3a; --ob-bg2:#10294a; --ob-bg3:#173058;
  --ob-ink:#e8edf4; --ob-ink2:#9db0c7; --ob-ink3:#5b7089;
  --ob-line:#1e3a63; --ob-line2:#28466f; --ob-hover:rgba(255,255,255,.05);
  --ob-card-shadow:0 18px 50px rgba(0,0,0,.45);
}
#screen-onboard{padding:0}
#screen-onboard.on{
  position:fixed; inset:0; z-index:50; display:flex; align-items:center; justify-content:center;
  padding:16px; overflow-y:auto;
  background:linear-gradient(to bottom,#ffffff 0,#ffffff 200px,var(--ob-blue) 200px,var(--ob-blue) 224px,var(--ob-bg) 224px);
}
html[data-theme="dark"] #screen-onboard.on{
  background:linear-gradient(to bottom,#10294a 0,#10294a 200px,var(--ob-blue) 200px,var(--ob-blue) 224px,var(--ob-bg) 224px);
}
#screen-onboard .obcard{
  width:100%; max-width:430px; margin:0; text-align:left;
  background:var(--ob-bg2); border:1px solid var(--ob-line); border-radius:22px;
  padding:22px; box-shadow:var(--ob-card-shadow); color:var(--ob-ink);
  font:13px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
#screen-onboard .hd{display:flex; align-items:center; gap:10px; margin-bottom:4px}
#screen-onboard .pyr{width:44px; height:auto}
#screen-onboard h1{font-size:19px; letter-spacing:.01em; font-weight:700; margin:0; font-family:inherit; color:var(--ob-ink)}
#screen-onboard .tag{font-size:11.5px; color:var(--ob-ink2); margin-bottom:14px}
#screen-onboard .tag b{color:#8d6f00}
html[data-theme="dark"] #screen-onboard .tag b{color:var(--ob-gold)}
#screen-onboard .pill{font-size:9.5px; padding:1px 7px; border-radius:99px; border:1px solid var(--ob-line2); color:var(--ob-ink3); text-transform:uppercase; letter-spacing:.05em; font-weight:400}
#screen-onboard label{display:block; margin:12px 0 4px; font-size:11.5px; color:var(--ob-ink2); font-weight:600; text-align:left}
#screen-onboard label .lbl2{color:var(--ob-ink3); font-weight:400}
#screen-onboard input,#screen-onboard textarea{
  width:100%; font:inherit; color:var(--ob-ink); background:var(--ob-bg3);
  border:1px solid var(--ob-line2); border-radius:var(--ob-r-sm); padding:6px 9px; outline:none;
}
#screen-onboard input:focus,#screen-onboard textarea:focus{border-color:var(--ob-acc)}
#screen-onboard ::placeholder{color:var(--ob-ink3)}
#screen-onboard .obtoggle{display:flex; gap:4px; margin-bottom:12px}
#screen-onboard .obtoggle button{flex:1; font-size:11.5px; padding:6px; border-radius:var(--ob-r-sm); border:1px solid var(--ob-line2); color:var(--ob-ink2); background:none; cursor:pointer}
#screen-onboard .obtoggle button.on{border-color:var(--ob-acc); color:var(--ob-ink); background:var(--ob-hover); font-weight:700}
#screen-onboard .row2{display:flex; gap:8px}
#screen-onboard .row2 .btn,#screen-onboard .row2 input{flex:1; min-width:0}
#screen-onboard .btn{
  background:linear-gradient(135deg,var(--ob-acc),var(--ob-blue-soft)); color:var(--ob-acc-ink);
  font-weight:700; font-size:12.5px; padding:8px 16px; border-radius:10px; border:none; cursor:pointer;
  box-shadow:0 8px 18px rgba(12,127,251,.22);
}
#screen-onboard .btn:disabled{opacity:.45; cursor:default; box-shadow:none}
#screen-onboard .btn.ghost{background:var(--ob-bg3); color:var(--ob-ink); border:1px solid var(--ob-line2); font-weight:600; box-shadow:none}
#screen-onboard .btn.gold{background:var(--ob-gold); color:#231c00; box-shadow:none}
#screen-onboard .btn.wide{width:100%}
#screen-onboard .feenote{font-size:10px; color:var(--ob-ink3); text-align:left; margin-top:0}
#screen-onboard .feenote b{color:var(--ob-ink2)}
#screen-onboard .linklike{display:block; margin:14px auto 0; background:none; border:none; color:var(--ob-blue); font-size:12px; cursor:pointer; text-decoration:underline; text-underline-offset:3px}
#screen-onboard .qrframe{display:flex; justify-content:center; margin:6px 0 2px}
#screen-onboard #obQrBox{width:190px; height:190px; border-radius:12px; background:#fff; border:1px solid var(--ob-line); display:flex; align-items:center; justify-content:center; position:relative}
#screen-onboard #obQrBox .qrph{font-family:var(--ob-mono); font-size:34px; color:var(--ob-line2); letter-spacing:2px}
#screen-onboard #obQrBox svg{width:100%; height:100%; display:block; border-radius:10px}
#screen-onboard .keybox{font-family:var(--ob-mono); font-size:10.5px; background:var(--ob-bg3); border:1px dashed var(--ob-line2); border-radius:var(--ob-r-sm); padding:8px; word-break:break-all; user-select:all; color:var(--ob-ink)}
#screen-onboard .savekey{display:flex; gap:8px; align-items:flex-start; margin-top:9px; font-size:11.5px; color:var(--ob-ink2)}
#screen-onboard .savekey input{width:auto; margin-top:2px}
#screen-onboard .settingsec{border-top:1px solid var(--ob-line); margin-top:12px; padding-top:10px}
#screen-onboard .settingsec h4{font-size:11px; text-transform:uppercase; letter-spacing:.07em; color:var(--ob-ink3); margin-bottom:6px}
#screen-onboard .spinner{display:inline-block; width:13px; height:13px; border:2px solid var(--ob-line2); border-top-color:var(--ob-blue); border-radius:50%; animation:spin .8s linear infinite; vertical-align:-2px; margin-right:4px}
@keyframes spin{to{transform:rotate(360deg)}}

/* The two ways in. Both buttons full width so neither reads as the "small"
   option; the Vault one is ghost so the lead is unambiguous. */
#screen-onboard #obChoose{ display:flex; flex-direction:column; gap:10px; margin:16px 0 4px; }
#screen-onboard #obChoose .btn{ height:46px; font-size:15px; font-weight:700; }
#screen-onboard #obBack{ margin-top:0; margin-bottom:10px; display:inline-block; }
#screen-onboard #obRoleBack{ margin-top:0; margin-bottom:10px; display:inline-block; }

/* THE SIGNUP FORK. Press-only - Chess has no equivalent - so it is built in
   the card's own idiom rather than invented: the same radius, line and hover
   colours as .btn.ghost, at the size #obChoose uses. */
#screen-onboard .rolegrid{ display:flex; flex-direction:column; gap:10px; margin:16px 0 4px; }
#screen-onboard .rolebtn{
  display:block; width:100%; text-align:left; cursor:pointer;
  background:var(--ob-bg3); color:var(--ob-ink);
  border:1px solid var(--ob-line2); border-radius:10px; padding:12px 14px;
  font:inherit;
}
#screen-onboard .rolebtn:hover{ border-color:var(--ob-acc); background:var(--ob-hover); }
#screen-onboard .roleTitle{ display:block; font-size:15px; font-weight:700; margin-bottom:3px; }
#screen-onboard .roleSub{ display:block; font-size:11.5px; color:var(--ob-ink2); line-height:1.45; }

/* ---- password fields: show/hide, and problems stated in place ----
   The eye sits INSIDE the field's box (the input reserves room for it via
   padding-right) so it never reflows the form when it appears. */
.pwwrap{ position:relative; display:block; }
.pwwrap input{ width:100%; padding-right:44px; }
.pweye{
  position:absolute; top:50%; right:6px; transform:translateY(-50%);
  width:32px; height:32px; display:flex; align-items:center; justify-content:center;
  border-radius:8px; color:var(--ob-ink3); cursor:pointer; padding:0;
  background:none; border:none;
}
#screen-onboard .pweye:hover{ color:var(--ob-ink); background:var(--ob-hover); }
.pweye svg{ width:20px; height:20px; display:block; }
.pweye.on{ color:var(--ob-acc); }
/* In Arabic and Hebrew the text starts on the RIGHT, so an eye pinned to the
   right sits on top of it. Mirror the whole arrangement, padding included.
   The onboarding card restyles its inputs behind an ID, which outranks a
   plain class rule - so the room for the eye has to be reserved at the same
   specificity, in both directions. */
html[dir="rtl"] .pwwrap input{ padding-right:12px; padding-left:44px; }
html[dir="rtl"] .pweye{ right:auto; left:6px; }
#screen-onboard .pwwrap input{ padding-right:44px; }
html[dir="rtl"] #screen-onboard .pwwrap input{ padding-right:9px; padding-left:44px; }

/* A mismatch is a STOP, not a whisper: red text under the field, both boxes
   outlined, stated the moment it is true rather than only on submit. */
.fieldErr{
  margin-top:8px; padding:9px 12px; border-radius:9px;
  border:2px solid #c62828; color:#c62828;
  font-size:13.5px; font-weight:700; line-height:1.4;
}
#screen-onboard .fieldErr{ color:#c62828; border-color:#c62828; background:rgba(198,40,40,.07); }
html[data-theme="hc"] #screen-onboard .fieldErr{ color:#8c0000; border-color:#8c0000; background:rgba(140,0,0,.10); }
input.err, .pwwrap input.err{ border-color:#c62828; box-shadow:0 0 0 3px rgba(224,40,40,.18); }
#screen-onboard input.err{ border-color:#c62828; box-shadow:0 0 0 3px rgba(198,40,40,.16); }

/* The account warning, repeated at the moment of no return. Bigger than the
   inline note by design - this is the last point where a forgotten password
   is still fixable. */
.obWarnBig{
  border:2px solid #c62828; border-radius:12px;
  padding:14px 16px; margin:4px 0 6px; font-size:15px; line-height:1.55;
}
.obWarnBig b.lead{ display:block; font-size:16px; margin-bottom:8px; }
.obWarnBig .hl{
  font-weight:800; background:rgba(245,199,17,.24);
  padding:1px 5px; border-radius:5px;
}

/* ---------------------------------------------------------------------
   Settings
   --------------------------------------------------------------------- */

.profBlock { border: 1px solid var(--rule); border-radius: 6px; padding: 0.9rem 1rem; margin-bottom: 1rem; }
.profName { font-family: var(--serif-display); font-size: 1.15rem; color: var(--navy); }

.modeRow { display: flex; gap: 0.3rem; margin-bottom: 1rem; }
.modebtn {
  flex: 1;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.4rem 0.3rem;
  font-size: 0.78rem;
  cursor: pointer;
}
.modebtn.on { color: var(--paper); background: var(--navy); border-color: var(--navy); }

.setPane { display: none; }
.setPane.on { display: block; }

.setRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--rule);
}

.setRow > span:first-child { flex: 1; }

.setRow select {
  font-family: var(--sans);
  font-size: 0.82rem;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
}

.setRow input[type='checkbox'] { width: 1.1rem; height: 1.1rem; flex: none; }

.setNote {
  font-size: 0.74rem;
  color: var(--muted);
  line-height: 1.5;
  margin: 0.4rem 0 0.8rem;
}

.verVal { font-size: 0.76rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.acctNote { font-size: 0.8rem; color: var(--muted); margin-bottom: 0.8rem; }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
}

body {
  font-family: var(--serif-body);
  font-size: var(--body-size);
  line-height: var(--leading);
  -webkit-text-size-adjust: 100%;
}

/* ---------------------------------------------------------------------
   The reading surface
   --------------------------------------------------------------------- */

/* Spec 17.5: articles render WITHOUT JavaScript. They are documents served
 * from nodes, and progressive enhancement is the right posture for a platform
 * whose whole claim is durability. Nothing in this block depends on script. */
.article {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 3rem 1.25rem 6rem;
}

.article h1 {
  font-family: var(--serif-display);
  font-size: 2.4em;
  line-height: 1.12;
  letter-spacing: -0.02em;   /* 17.3: tight tracking at large sizes */
  color: var(--navy);
  margin: 0 0 0.4em;
  font-weight: 600;
}

.article h2 {
  font-family: var(--serif-display);
  font-size: 1.45em;
  line-height: 1.22;
  color: var(--navy);
  margin: 2em 0 0.5em;
  font-weight: 600;
}

.article .subtitle {
  font-size: 1.15em;
  color: var(--muted);
  margin: 0 0 1.6em;
  line-height: 1.4;
}

.article p { margin: 0 0 1.35em; }

.article a {
  color: var(--blue);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

.article blockquote {
  margin: 1.6em 0;
  padding-left: 1.2em;
  border-left: 3px solid var(--rule);
  color: var(--muted);
}

.article pre {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.82em;
  line-height: 1.5;
  background: rgba(11, 42, 74, 0.04);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.9em 1em;
  /* Wide content scrolls inside its own box; the page never scrolls
   * horizontally. */
  overflow-x: auto;
}

.article img,
.article video { max-width: 100%; height: auto; }

/* Images in a piece. A figure not yet verified holds its place quietly; one
 * that cannot be verified says so in words. Never a broken-image glyph. */
.body-img { margin: 2rem 0; }
.body-img img {
  display: block;
  width: 100%;
  border-radius: 3px;
  background: var(--rule);
  min-height: 6rem;
}
.body-img.loaded img { min-height: 0; background: transparent; }
.body-img figcaption {
  font-family: var(--sans);
  font-size: 0.76rem;
  color: var(--muted);
  margin-top: 0.5rem;
  text-align: center;
}
.body-img figcaption:empty { display: none; }
.body-img.missing {
  border: 1px dashed var(--rule);
  border-radius: 3px;
  padding: 1.2rem;
}
.body-extlink { font-family: var(--sans); font-size: 0.85rem; color: var(--muted); overflow-wrap: anywhere; }

/* ---------------------------------------------------------------------
   Byline and the provenance strip (17.4)
   --------------------------------------------------------------------- */

.byline {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.4rem;
}

.byline .pen-name {
  color: var(--ink);
  font-weight: 600;
  font-size: 0.85rem;
}

/* THE SIGNATURE ELEMENT. A compact horizontal element under the byline
 * rendering the piece's composition record as a sparkline of writing sessions
 * over time, with paste events marked. Present on opt-in, absent otherwise,
 * NEVER a warning (17.4, 7.6).
 *
 * Quiet and factual. It is not a badge and not a score, and the copy around it
 * must never imply that a piece without one is suspect - journalists who
 * compose mentally and type clean, dictation users, assistive input users,
 * non-native speakers drafting elsewhere, and mobile writers all produce
 * records that look synthetic and are exactly the writers worth having. */
.provenance {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--muted);
}

/* GOLD IS RESERVED FOR EXACTLY ONE CLASS OF THING: verified provenance
 * (17.2). If gold appears anywhere that is not a provenance claim, it is a
 * bug - the whole visual system depends on that association holding. It is
 * used here as a mark and a rule, never as text: #f5c711 on paper is about
 * 1.7:1 and is unreadable as type. */
.provenance .mark {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--gold);
  flex: none;
}

.provenance svg { display: block; }
.provenance .session { fill: var(--navy); }
.provenance .paste { fill: var(--gold); }

/* Absence is stated neutrally (7.6): "no composition record", never a
 * warning colour, never an icon that reads as a caution. */
.provenance.absent .mark { background: var(--rule); }

/* ---------------------------------------------------------------------
   Highlights (9.5)
   --------------------------------------------------------------------- */

.hl {
  background: rgba(245, 199, 17, 0.22);
  border-radius: 2px;
  padding: 0.05em 0;
}

.hl-heat-1 { background: rgba(245, 199, 17, 0.14); }
.hl-heat-2 { background: rgba(245, 199, 17, 0.28); }
.hl-heat-3 { background: rgba(245, 199, 17, 0.44); }

/* ---------------------------------------------------------------------
   Support (6.9, 12.14)
   --------------------------------------------------------------------- */

/* Deliberately calm. No urgency styling, no red, no alarm colours, no icon
 * that reads as a warning - a reader who sends something should feel they
 * backed something good, not that they paid a ransom. This block uses the
 * same hairline and muted tones as the rest of the page for exactly that
 * reason, and gold does not appear anywhere in it because gold means verified
 * provenance and nothing else (17.2). */
.support {
  max-width: var(--measure);
  margin: 3rem auto 0;
  padding: 1.4rem 0 0;
  border-top: 1px solid var(--rule);
  font-family: var(--sans);
}

.support-title {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.5rem;
}

.support-note {
  font-size: 0.9rem;
  color: var(--ink);
  margin: 0 0 0.9rem;
  line-height: 1.45;
}

.support-amounts { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }

.support-custom {
  font-family: var(--sans);
  font-size: 0.85rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  width: 7rem;
}

.support-status { font-size: 0.78rem; margin: 0.6rem 0 0; min-height: 1.2em; }

/* The writer's own funding view. Theirs alone, never rendered to a reader
 * (12.14) - a funded-through figure a reader can see is a countdown. Styled
 * as ordinary metadata, never as an alert. */
.funding {
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--muted);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.9rem 1rem;
}

.funding strong { color: var(--ink); }
.funding p { margin: 0 0 0.35rem; }
.funding p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------
   Controls
   --------------------------------------------------------------------- */

/* `.btn` is used by the MODALS as well as by the sign-in card. The card has
 * its own scoped copies above, in Chess's palette; these are the app-theme
 * versions for everything else. Both are needed - deleting these left every
 * settings button unstyled, which is how this comment came to exist. */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--paper);
  background: var(--navy);
  border: 1px solid var(--navy);
  border-radius: 6px;
  padding: 0.5rem 1rem;
  cursor: pointer;
  text-align: center;
}

.btn.wide { display: block; width: 100%; }
.btn.ghost { background: transparent; color: var(--blue); border-color: var(--rule); font-weight: 500; }
.btn.gold { background: var(--navy); }
.btn.sm { font-size: 0.76rem; padding: 0.35rem 0.7rem; }
.btn[disabled] { opacity: 0.5; cursor: default; }
/* The danger variant exists for exactly one class of act: the irreversible.
 * If it appears anywhere reversible, that is a bug (Chess uses it the same
 * way). */
.btn.danger { background: #c62828; }
.btn.danger[disabled] { background: #c62828; }

button,
.button {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--paper);
  background: var(--navy);
  border: 1px solid var(--navy);
  border-radius: 4px;
  padding: 0.5rem 0.95rem;
  cursor: pointer;
}

button.quiet,
.button.quiet {
  background: transparent;
  color: var(--blue);
  border-color: var(--rule);
}

button[disabled] { opacity: 0.5; cursor: default; }

/* 17.5: visible keyboard focus. Uses the bright blue, which is a large
 * non-text indicator and passes the 3:1 threshold that applies to it. */
:focus-visible {
  outline: 3px solid var(--blue-bright);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------
   Chain-derived values
   --------------------------------------------------------------------- */

/* I-16: the client never decides value. A figure that has not arrived from
 * the chain renders as '-', never as a default or a zero. The dimmed style
 * makes a pending figure visibly pending rather than looking like a real
 * result of nothing. */
/* Avatars - the ITZA rounded square (Chess's .chipAv values, scaled).
 * object-position keeps faces: crop from the top, never the middle of a
 * forehead. One shape at three sizes; gold never appears here (17.2). */
.avatar {
  border-radius: 8px;
  object-fit: cover;
  object-position: center top;
  background: var(--rule);
  box-shadow: 0 0 0 1.5px var(--rule);
  flex: none;
}
.av-byline { width: 40px; height: 40px; }
.av-feed { width: 20px; height: 20px; border-radius: 5px; vertical-align: -5px; margin-right: 2px; }
.av-profile { width: 64px; height: 64px; margin-right: 0.9rem; }
.av-desk { width: 34px; height: 34px; margin-right: 0.6rem; }
.desk-idwrap { display: flex; align-items: center; }
.profTop { display: flex; align-items: center; }

/* The engagement row - quiet, Medium-familiar, under the byline. */
.engage {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.9rem 0 0.4rem;
}

.engage-btn {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--navy);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 99px;
  padding: 0.3rem 0.85rem;
  cursor: pointer;
}

.engage-btn:hover { border-color: var(--blue); color: var(--blue); }

/* Follow, not yet following: the ITZA primary - the same blue gradient the
 * sign-in card's buttons wear, so "the button that acts" looks the same in
 * every ITZA app. Following flips to quiet navy: a held state, not a call. */
#engFollow {
  color: #ffffff;
  background: linear-gradient(135deg, #0c7ffb, #1d6fd0);
  border: none;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(12, 127, 251, 0.22);
}
#engFollow:hover { color: #ffffff; filter: brightness(1.06); }
#engFollow.on {
  background: var(--navy);
  box-shadow: none;
  font-weight: 500;
}

/* Kept things are GOLD - the saved bookmark fills in brand gold, and the
 * listening state runs blue while the voice reads. */
.engage-btn.on { color: var(--paper); background: var(--navy); border-color: var(--navy); }
#engSave.on { color: #b8930a; background: rgba(245, 199, 17, 0.14); border-color: #b8930a; }
#engListen.on { color: var(--paper); background: var(--blue); border-color: var(--blue); }
.engage-btn[disabled] { opacity: 0.6; cursor: default; }

/* Icon buttons in the engagement row: the icon IS the label visually; the
 * accessible name rides on aria-label and the tooltip. */
.engage-btn.icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 30px;
  padding: 0;
}
.engage-btn.icon svg { width: 17px; height: 17px; }

/* The share menu - the marketing site's warm card, not a generic dropdown:
 * paper surface, hairline rule, a navy-tinted shadow, and the wordmark's
 * blue-into-gold pairing as a slim bar across the top. Icons sit navy and
 * turn blue on hover, exactly as the site's links behave. */
.sharemenu {
  position: absolute;
  z-index: 70;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 12px;
  box-shadow: 0 12px 38px rgba(11, 42, 74, 0.2);
  padding: 0.35rem;
  min-width: 13.5rem;
  font-family: var(--sans);
  overflow: hidden;
}

.sharemenu::before {
  content: '';
  display: block;
  height: 3px;
  margin: -0.35rem -0.35rem 0.35rem;
  background: linear-gradient(90deg, #0c7ffb, #f5c711);
}

.sharemenu-row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  text-align: left;
  font-size: 0.85rem;
  color: var(--ink);
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 0.5rem 0.65rem;
  cursor: pointer;
}

.sharemenu-row:hover { background: rgba(12, 127, 251, 0.07); color: var(--navy); }
html[data-theme='dark'] .sharemenu-row:hover { background: rgba(255, 255, 255, 0.06); }
.sharemenu-row svg { width: 17px; height: 17px; flex: none; color: var(--navy); }
.sharemenu-row:hover svg { color: var(--blue); }
html[data-theme='dark'] .sharemenu-row svg { color: var(--muted); }
.sharemenu-rule { height: 1px; background: var(--rule); margin: 0.3rem 0.4rem; }

/* The selection popover - Medium's shape in ITZA's clothes (user-directed
 * 2026-08-02): the pill is CORPORATE NAVY, and hover is GOLD ON NAVY - the
 * same pairing the marketing site's navy bands use for their links, which
 * is the closest thing ITZA has to a signature. */
.selpop {
  position: absolute;
  z-index: 65;
  display: flex;
  align-items: center;
  background: #0b2a4a;
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(11, 42, 74, 0.4);
  padding: 4px;
  /* The wordmark pairing, blue into gold, as a hairline signature. */
  border-bottom: 2px solid transparent;
  border-image: linear-gradient(90deg, #0c7ffb, #f5c711) 1;
}

.selpop[hidden] { display: none; }

.selpop button {
  font-family: var(--sans);
  font-size: 0.8rem;
  color: #fbfaf7;
  background: transparent;
  border: none;
  border-radius: 6px;
  padding: 7px 12px;
  cursor: pointer;
  white-space: nowrap;
}

.selpop button:hover { color: #f5c711; background: rgba(255, 255, 255, 0.06); }
.selpop button + button { border-left: 1px solid rgba(251, 250, 247, 0.16); border-radius: 0 6px 6px 0; }

/* Quotes inside the respond / note dialogs, and the notes section. */
.selquote {
  font-family: var(--serif-body);
  font-size: 0.9rem;
  color: var(--muted);
  border-left: 3px solid var(--rule);
  margin: 0.6rem 0 0.8rem;
  padding: 0.2rem 0 0.2rem 0.8rem;
}

#modal textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 0.88rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0.55rem 0.7rem;
  resize: vertical;
}

.notes-slot { margin-top: 3rem; border-top: 1px solid var(--rule); padding-top: 1.2rem; }
.notes-head {
  font-family: var(--serif-display);
  font-size: 1.15rem;
  color: var(--navy);
  margin: 0 0 0.2rem;
  display: inline-block;
  border-bottom: 2px solid var(--gold);
  padding-bottom: 2px;
}
.notes-sub { font-size: 0.74rem; margin: 0 0 1rem; }
.note { margin-bottom: 1.2rem; }
.note blockquote {
  font-family: var(--serif-body);
  font-size: 0.9rem;
  color: var(--muted);
  border-left: 3px solid var(--gold);
  margin: 0 0 0.35rem;
  padding-left: 0.8rem;
}
.note p { font-family: var(--sans); font-size: 0.88rem; margin: 0 0 0.25rem; }
.note-del {
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--muted);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Topic chips (the writer's tags) - rounded pills in the ITZA idiom. A
 * plain chip on the article; a link chip that turns blue on hover in the
 * feed and browse views, matching every other link on the site. */
.topic-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.6rem 0 0; }
.tag-chip {
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--navy);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 99px;
  padding: 0.2rem 0.7rem;
  text-decoration: none;
  white-space: nowrap;
}
.tag-chip.link:hover { border-color: var(--blue); color: var(--blue); }

/* The publish dialog's tag field and its live chip preview. */
.pubtags { margin: 0.4rem 0 0.8rem; }
.pubtags label { display: block; font-family: var(--sans); font-size: 0.82rem; margin-bottom: 0.35rem; }
.pubtags input {
  width: 100%;
  font-family: var(--sans);
  font-size: 0.88rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
}
.pubtag-preview { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.5rem; }
.pubtag-preview .tag-chip { border-color: var(--gold); color: #ad8009; }

/* Embedded attachments in the EDITOR: the picture in the page, atomic and
   quietly furnished. The name rides in CSS content so the figure contributes
   no text to the document model. */
.ed-embed {
  position: relative;
  margin: 1.4rem 0;
  max-width: 100%;
}

.ed-embed img,
.ed-embed video {
  display: block;
  max-width: 100%;
  max-height: 320px;
  border-radius: 6px;
}

.ed-embed video { background: #000; }
.ed-embed audio { display: block; width: 100%; }

.ed-embed::after {
  content: attr(data-name);
  display: block;
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--muted);
  margin-top: 0.35rem;
}

.ed-embed.missing {
  border: 1px dashed var(--rule);
  border-radius: 6px;
  padding: 1rem;
}

.ed-embed-x {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  width: 1.6rem;
  height: 1.6rem;
  border: none;
  border-radius: 50%;
  background: rgba(10, 25, 47, 0.65);
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms;
}

.ed-embed:hover .ed-embed-x,
.ed-embed-x:focus-visible { opacity: 1; }

.ed-embed-x::before {
  content: '\00d7';
  color: #fff;
  font-size: 1rem;
  line-height: 1;
}

/* Video and audio in a body. Same figure furniture as an image so a mixed
   entry reads as one column. */
.body-media { margin: 1.6rem 0; }

.body-media video {
  display: block;
  width: 100%;
  max-height: 70vh;
  border-radius: 6px;
  background: #000;
}

.body-media audio { display: block; width: 100%; }

.body-media figcaption {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.45rem;
}

.body-missing {
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--muted);
  border-left: 3px solid var(--rule);
  padding-left: 0.8rem;
}

/* Forms inside a modal dialog. Bare labels and inputs flow INLINE in HTML,
 * which is what made the give-access dialog look like a ransom note (user
 * screenshot, 2026-08-05). Any dialog form gets the stacked treatment by
 * wrapping its fields in .mform - one class, consistent everywhere. */
.mform label {
  display: block;
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--ink);
  margin: 0.95rem 0 0.3rem;
}

.mform input,
.mform textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font-family: var(--sans);
  font-size: 0.92rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0.55rem 0.7rem;
}

.mform .setNote { margin-top: 0.9rem; }

/* The diary. Deliberately quieter than the public surfaces - it is a
 * private room, not a shopfront. Gold marks the locked/unlocked state,
 * which is the one thing a diarist must never misread. */
.diary-gate { max-width: 26rem; }
.diary-gate label { display: block; font-family: var(--sans); font-size: 0.82rem; margin: 0.9rem 0 0.3rem; }
/* Air between the last field and the button - they sat touching. */
.diary-gate .btn { margin-top: 1.2rem; }
.diary-gate .fieldErr { margin: 0.8rem 0 0; }
.diary-gate input {
  width: 100%;
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
}

.diary-list { border-top: 1px solid var(--rule); margin-top: 1.4rem; }

.diary-row {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  border-bottom: 1px solid var(--rule);
  padding: 0.2rem 0;
  flex-wrap: wrap;
}

.diary-open {
  flex: 1;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  padding: 0.85rem 0.25rem;
  color: inherit;
}

.diary-open:hover .diary-title { color: var(--blue); }

.diary-title {
  font-family: var(--serif-display);
  font-size: 1.1rem;
  color: var(--navy);
}

.diary-date { font-size: 0.74rem; color: var(--muted); white-space: nowrap; }

.diary-body {
  flex-basis: 100%;
  padding: 0.2rem 0.25rem 1.1rem;
  font-family: var(--serif-body);
  font-size: var(--body-size);
  line-height: var(--leading);
  border-left: 3px solid var(--gold);
  margin: 0 0 0.6rem 0.25rem;
  padding-left: 0.9rem;
}

.diary-body[hidden] { display: none; }

.settingsec-h {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1.4rem 0 0.5rem;
}

/* The waiting state. Motion is the whole point - a static line during a
 * wait is what made the app look stuck - so it is deliberately small and
 * calm, and it respects reduced-motion like everything else. */
.loading {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--muted);
  padding: 1.5rem 0;
}

.loading-dots { display: inline-flex; gap: 4px; }

.loading-dots i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--muted);
  opacity: 0.35;
  animation: loadingPulse 1.1s ease-in-out infinite;
}

.loading-dots i:nth-child(2) { animation-delay: 0.16s; }
.loading-dots i:nth-child(3) { animation-delay: 0.32s; }

@keyframes loadingPulse {
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-3px); }
}

.figure { font-family: var(--sans); font-variant-numeric: tabular-nums; }
.figure.pending { color: var(--muted); }

/* Entitlement is NOT a balance and must never be styled as one (spec 14).
 * Copy is "Unvested earnings. Verify once to claim." - never "Your balance." */
.entitlement { font-family: var(--sans); color: var(--muted); }

/* ---------------------------------------------------------------------
   Editor (12.1)
   --------------------------------------------------------------------- */

/* Distraction-free by default (12.1): a title, a subtitle, the text, and one
 * quiet bar. The formatting tools exist only over a selection. */

.edbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.55rem 1.25rem;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--muted);
}

.edbar-back {
  color: var(--blue);
  text-decoration: none;
  white-space: nowrap;
}
.edbar-back:hover { text-decoration: underline; }

.edbar-state {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
}

.edbar-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--rule); flex: none; }

.edbar-actions {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  white-space: nowrap;
}

.edbar-quiet { color: var(--muted); font-size: 0.72rem; }
.edbar-quiet:empty { display: none; }

.editor-wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 2.5rem 1.25rem 8rem;
}

.title-input,
.subtitle-input {
  display: block;
  width: 100%;
  border: none;
  outline: none;
  background: transparent;
  resize: none;
  overflow: hidden;
  padding: 0;
}

.title-input {
  font-family: var(--serif-display);
  font-size: 2.2em;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin-bottom: 0.35rem;
}

.subtitle-input {
  font-family: var(--serif-body);
  font-size: 1.1em;
  line-height: 1.4;
  color: var(--muted);
  margin-bottom: 1.6rem;
}

.title-input::placeholder,
.subtitle-input::placeholder { color: var(--muted); opacity: 0.55; }

.editor {
  min-height: 55vh;
  outline: none;
  font-family: var(--serif-body);
  font-size: var(--body-size);
  line-height: var(--leading);
  color: var(--ink);
  /* THE TEXT MODEL: newlines are real characters and must render as such.
   * Without this, a loaded draft's paragraphs collapse into one line. */
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.editor:empty::before {
  content: attr(data-placeholder);
  color: var(--muted);
  opacity: 0.55;
}

/* The selection toolbar - present only over a selection, floats above it. */
.edtools {
  position: absolute;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--navy);
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(11, 42, 74, 0.35);
}

.edtools[hidden] { display: none; }

.edtool {
  font-family: var(--sans);
  font-size: 0.8rem;
  line-height: 1;
  color: var(--paper);
  background: transparent;
  border: none;
  border-radius: 5px;
  padding: 7px 9px;
  cursor: pointer;
  min-width: 30px;
}

.edtool:hover { background: rgba(255, 255, 255, 0.14); }
.edtool b, .edtool i { font-family: var(--serif-body); }

.edtools-rule { width: 1px; align-self: stretch; margin: 4px 3px; background: rgba(255, 255, 255, 0.25); }

/* Preview renders through the article styles - it IS the article. */
.edpreview { padding-top: 0; }
.edpreview[hidden] { display: none; }

/* First-run guidance (12.2): a quiet card, not a tour and not a modal. */
.edguide,
.dguide {
  max-width: var(--measure);
  margin: 1.5rem auto 0;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--gold);
  border-radius: 6px;
  font-family: var(--sans);
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--ink);
}

.edguide h2,
.dguide h2 {
  font-family: var(--serif-display);
  font-size: 1.15rem;
  color: var(--navy);
  margin: 0 0 0.6rem;
}

.edguide p,
.dguide p { margin: 0 0 0.6rem; }
.edguide b,
.dguide b { color: var(--navy); }

/* The diary's copy of the guide sits inside .article, which already has its
 * own measure - so it fills that rather than imposing a second one. */
.dguide { max-width: none; margin: 1.2rem 0 0; }

/* ---------------------------------------------------------------------
   The desk - the writer's home
   --------------------------------------------------------------------- */

.desk {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 5rem;
}

.desk-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2.2rem;
}

.desk-head h1 {
  font-family: var(--serif-display);
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin: 0 0 0.3rem;
}

.desk-id {
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--muted);
  margin: 0;
}

.desk-new { flex: none; text-decoration: none; }

.desk-sec { margin-bottom: 2.2rem; }

.desk-label {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.4rem;
}

.desk-list { border-top: 1px solid var(--rule); }

.desk-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0.25rem;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
}

.desk-row:hover { background: rgba(11, 42, 74, 0.03); }
html[data-theme='dark'] .desk-row:hover { background: rgba(255, 255, 255, 0.04); }

.desk-row-main { min-width: 0; }

.desk-row-title {
  display: block;
  font-family: var(--serif-display);
  font-size: 1.1rem;
  line-height: 1.25;
  color: var(--navy);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.desk-row-meta {
  display: block;
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--muted);
  margin-top: 0.15rem;
}

.desk-row-fig {
  flex: none;
  font-size: 0.76rem;
  color: var(--muted);
}

.pubstore { margin: 1rem 0 0.4rem; }
.pubopt {
  display: flex;
  gap: 0.55rem;
  align-items: flex-start;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  margin-bottom: 0.5rem;
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1.45;
}
.pubopt:hover { border-color: var(--muted); }
.pubopt input { margin-top: 0.2rem; flex: none; }
.pubstore .linklike {
  background: none; border: none; cursor: pointer;
  color: var(--blue); font-size: 0.78rem; padding: 0;
  text-decoration: underline; text-underline-offset: 3px;
}

.desk-row-act {
  flex: none;
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.25rem 0.55rem;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.desk-row:hover .desk-row-act,
.desk-row-act:focus-visible { opacity: 1; }

/* Diary rows carry the same quiet action - and must TRIGGER it too. The
 * class was borrowed from the desk but the reveal was bound to .desk-row,
 * so the diary's Remove button existed at opacity 0 forever (user report,
 * 2026-08-05: "there's no way to delete"). */
.diary-row:hover .desk-row-act,
.diary-row:focus-within .desk-row-act { opacity: 1; }

.desk-row-act:hover { color: var(--ink); border-color: var(--muted); }

.desk-row.down .desk-row-title { color: var(--muted); }

/* Touch screens have no hover: the action is simply always there. */
@media (hover: none) {
  .desk-row-act { opacity: 1; }
}

.byline-act {
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.2rem 0.5rem;
  cursor: pointer;
  margin-left: auto;
}

.byline-act:hover { color: var(--ink); border-color: var(--muted); }

.desk-empty {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--muted);
  padding: 0.85rem 0.25rem;
  border-bottom: 1px solid var(--rule);
  margin: 0;
}

.desk-empty a { color: var(--blue); }

.desk-more {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.4rem;
  font-family: var(--sans);
  font-size: 0.8rem;
  padding-top: 0.5rem;
}

.desk-more a { color: var(--blue); text-decoration: none; }
.desk-more a:hover { text-decoration: underline; }

@media (max-width: 34rem) {
  .desk-head { flex-direction: column; align-items: flex-start; }
  .desk-row-fig { display: none; }
}

/* ---------------------------------------------------------------------
   Money (10.1, 12.12, 6.4)
   --------------------------------------------------------------------- */

.subscribe { margin: 2rem 0; }

.sub-amount {
  font-family: var(--sans);
  font-size: 0.85rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  width: 9rem;
}

.earnings {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--sans);
  font-size: 0.85rem;
  margin: 0 0 1.5rem;
}

.earnings th[scope='row'] {
  text-align: left;
  font-weight: 400;
  color: var(--muted);
  padding: 0.45rem 1rem 0.45rem 0;
  border-bottom: 1px solid var(--rule);
}

.earnings td {
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--rule);
}

/* The derivation table is the differentiator: every incumbent shows a number,
 * this shows the arithmetic (12.12, I-8). Wide, so it scrolls in its own box
 * rather than making the page scroll. */
.derivation {
  display: block;
  overflow-x: auto;
  white-space: nowrap;
  font-size: 0.76rem;
}

.derivation th { text-align: left; color: var(--muted); font-weight: 600; padding-right: 1rem; }
.derivation td { text-align: left; padding-right: 1rem; }

/* Entitlement is styled as its OWN block, never as a row in a table of money
 * the writer has. It is a conditional claim that does not vest without
 * verification, and the visual separation carries that as much as the copy
 * does (spec 14, 5.5). */
.entitlement {
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--muted);
  border: 1px dashed var(--rule);
  border-radius: 4px;
  padding: 0.9rem 1rem;
  margin: 1.5rem 0;
}

.entitlement strong { color: var(--ink); }
.entitlement p { margin: 0 0 0.4rem; }
.entitlement p:last-child { margin-bottom: 0; }

/* The conversion split. Both ends of the slider are given equal visual weight
 * on purpose - neither extreme is the wrong answer (6.4). */
.split { margin: 2rem 0; }
.split-range { width: 100%; max-width: 26rem; }

.split-ends {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  max-width: 26rem;
  font-size: 0.72rem;
}

.split-ends span { flex: 1 1 0; }
.split-ends span:last-child { text-align: right; }

/* ---------------------------------------------------------------------
   Discovery (9.1, 9.2, 12.13)
   --------------------------------------------------------------------- */

.feed-nav, .home-nav { font-family: var(--sans); font-size: 0.85rem; }
.feed-nav { margin: 0 0 2rem; display: flex; gap: 1rem; flex-wrap: wrap; }
.feed-nav a, .home-nav a { color: var(--blue); }

.feed-item {
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--rule);
}

.feed-item h2 {
  font-family: var(--serif-display);
  font-size: 1.35em;
  line-height: 1.2;
  margin: 0 0 0.25rem;
  color: var(--navy);
  font-weight: 600;
}

.feed-item h2 a { color: inherit; text-decoration: none; }
.feed-item h2 a:hover { text-decoration: underline; }
.feed-sub { margin: 0 0 0.35rem; color: var(--muted); font-size: 0.95em; }
.feed-meta { font-size: 0.75rem; color: var(--muted); margin: 0; }

.feed-note { font-size: 0.75rem; color: var(--muted); margin-top: 2rem; }

.search-q {
  font-family: var(--sans);
  font-size: 0.9rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  min-width: 16rem;
  max-width: 100%;
}

/* ---------------------------------------------------------------------
   Rating (8.2)
   --------------------------------------------------------------------- */

/* Two choices, equal weight, no scale. There is deliberately no third option
 * that reads as a score and nothing that could be averaged. */
.rate-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.8rem;
  margin: 1.5rem 0;
}

.rate-choice {
  font-family: var(--serif-display);
  font-size: 1.05rem;
  line-height: 1.3;
  text-align: left;
  padding: 1.1rem;
  min-height: 5rem;
  background: transparent;
  color: var(--navy);
  border: 1px solid var(--rule);
}

.rate-choice:hover { border-color: var(--navy); }

@media (max-width: 34rem) {
  .rate-pair { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------
   Removal log (11.4)
   --------------------------------------------------------------------- */

/* Presented as a public record, not as a warning. No red, no alarm styling -
 * this page exists to be auditable, and a log that looks like an incident
 * report reads as an admission rather than as transparency. */
.removal-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--sans);
  font-size: 0.78rem;
  margin: 1rem 0 2rem;
  /* Wide content scrolls inside its own box; the page never scrolls
   * horizontally. */
  display: block;
  overflow-x: auto;
  white-space: nowrap;
}

.removal-table th {
  text-align: left;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 1px solid var(--rule);
  padding: 0.4rem 0.8rem 0.4rem 0;
}

.removal-table td {
  padding: 0.4rem 0.8rem 0.4rem 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}

/* ---------------------------------------------------------------------
   Quality floor (17.5)
   --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 34rem) {
  .article,
  .editor-wrap { padding-left: 1rem; padding-right: 1rem; }
  .article h1 { font-size: 1.9em; }
  .edbar { flex-wrap: wrap; gap: 0.5rem; padding: 0.5rem 1rem; }
  .edbar-state { order: 3; flex-basis: 100%; }
}

/* ---------------------------------------------------------------------
   Paper-diary import: the page and its words, side by side
   --------------------------------------------------------------------- */

.desk-acts { display: flex; gap: 0.5rem; align-items: center; }

.dimp {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 4fr);
  gap: 1.25rem;
  margin: 1rem 0;
}
.dimp-img {
  margin: 0;
  border: 1px solid var(--rule);
  border-radius: 8px;
  overflow: hidden;
  background: var(--paper);
  align-self: start;
}
.dimp-img img { display: block; width: 100%; height: auto; }
.dimp-side { display: flex; flex-direction: column; gap: 0.75rem; min-width: 0; }
.dimp-text {
  min-height: 16rem;
  resize: vertical;
  font: inherit;
  color: var(--ink);
  padding: 0.75rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper);
}
.dimp-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: space-between;
  align-items: center;
}
.dimp-nav { display: flex; gap: 0.5rem; }
.dimp-done { display: flex; justify-content: flex-end; margin: 1rem 0 2rem; }
.dimp-again { display: flex; gap: 0.5rem; align-items: center; }

.dimp-last { max-width: 28rem; margin: 1rem auto; }
.dimp-snap-acts { justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }

@media (max-width: 700px) {
  .dimp { grid-template-columns: 1fr; }
}
