/* Cite operator kit: the marketing pages' craft, in the tools (Nov 2026).

   How to use
   ──────────
   Load after paste/tokens.css, components.css, tool.css and paper.css (and
   after lib/operator.css where a tool links it), and import the helpers
   from paste/operator-kit.js (they write this markup).

   - Readable type: the --t-* tokens below are the operator type scale
     (the owner's, Nov 2026: body 17px on a desk and 16px on a phone, hints
     15px in --ink2, labels 16px at 650+, buttons and tabs 16px, card titles
     19-22px, fine print 13.5px only for footers and timestamps, body line
     height 1.5). Any tool may use the tokens; putting .op-readable on
     <body> also applies them to the shared shell's classes (.why, .hint,
     .lbl, .btn, .cx, tabs, rows, the sidebar) and to the inputs.
   - A page hero: .op-hero holds .op-hero-copy (.op-kick, .op-title, .op-line,
     .op-acts) and an optional .op-hero-art (a torn cut-out, .op-cutout, with
     a taped .op-hero-tag over it). heroHtml() draws all of it. One hero per
     section; the title is the page's h1 and the line says what it is for.
   - Weight: .tcard.op-primary is the one card a section is about (taped, a
     size up, lifted); .tcard.op-secondary is everything that only informs
     (flat on the ground, smaller head). Plain .tcard stays in between.
   - Paper, sparingly: .op-stamp is a rubber-stamped word on anything;
     .op-taped puts a strip of tape on a block that has no ::after of its own.
     For torn edges use paper.css's .cut.tear-b / .tear-t.
   - Motion: reveal(root) rises a section's [data-op-reveal] parts in once;
     anything with .op-press presses in; flip(el, label, paint) turns a
     status plate over like the enamel plate on /business; pop(el) says a
     save landed; .op-skel lines shimmer while something loads. All of it
     stands still under prefers-reduced-motion.
   - States: emptyHtml({ art, title, line, action }) is the one empty state,
     a small collage tile and one line of copy.
   - Tabs and segments are lib/operator.css's (.v-seg, .d-seg, .op-tabs):
     the pick is underlined in ink, never filled. Option chips stay chips. */

/* ── Readable type ── */
:root {
  --t-body: 17px; --t-hint: 15px; --t-label: 16px; --t-btn: 16px; --t-tab: 16px;
  --t-card: 21px; --t-card-sm: 19px; --t-fine: 13.5px; --lh-body: 1.5;
}
@media (max-width: 720px) { :root { --t-body: 16px; --t-card: 19.5px; } }

body.op-readable {
  font-size: var(--t-body); line-height: var(--lh-body);
  /* The desk's scale, which the older vendor sheets size by, lifted to it. */
  --t-11: 13.5px; --t-12: 14.5px; --t-13: 15px; --t-14: 16px; --t-15: 16.5px; --t-16: 17px;
}
/* Contrast: on the warm grounds the third ink sat just under AA (4.3:1), and
   the faint ink (2.3:1) was carrying words. Words get the third ink, a shade
   deeper in light; faint stays for rules, placeholders and art. The desk
   aliases are re-pointed here because :root resolved them already. */
body.op-readable { --ink3: #5B574F; }
:root[data-theme="dark"] body.op-readable { --ink3: #B3A996; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) body.op-readable { --ink3: #B3A996; } }
body.op-readable { --ink-3: var(--ink3); --ink-4: var(--ink3); }
body.op-readable :is(.side-nav .grp, .v-side-nav .grp, .legal-links, .dk-pal-group, .palette .ph) { color: var(--ink3); }
body.op-readable .v-step-n { color: var(--ink2); }
/* Body copy and fields. 16px is also what keeps iOS from zooming into a field. */
body.op-readable :is(p, li, .op-line) { line-height: var(--lh-body); }
body.op-readable :is(input, textarea, .inp, .area, .sel, .v-input) { font-size: max(16px, var(--t-body)); }
body.op-readable :is(.tcard, .d-card) p:not([class]) { font-size: var(--t-body); }
/* Helper lines: a size up and never fainter than the second ink. */
body.op-readable :is(.why, .hint, .d-card-sub, .dk-panel-sub, .v-note-hint, .v-claim-hint, .vp-sign-why, .v-state-why, .d-empty, .v-pop-empty, .muted) { font-size: var(--t-hint); line-height: 1.45; color: var(--ink2); }
body.op-readable .vp-state .v-state-why { font-size: var(--t-hint); color: var(--ink2); }
body.op-readable .tcard.field :is(.why, .muted) { color: var(--on-field2); }
/* Labels. */
body.op-readable :is(.lbl, .v-label, .v-field > span:first-child, .v-field-k, .op-label-lg) { font-size: var(--t-label); font-weight: 700; color: var(--ink); }
body.op-readable :is(.lbl, .v-label) .muted { font-size: var(--t-hint); font-weight: 600; }
/* Buttons, chips, tabs and segments. */
body.op-readable :is(.btn, .v-btn, .d-act, .cx, .v-chip-btn, .v-hr, .v-btn-quiet) { font-size: var(--t-btn); }
body.op-readable :is(.btn.sm, .v-btn-sm, .cx.sm) { font-size: 15.5px; }
body.op-readable :is(.tabs > *, .seg > *, .v-seg > button, .d-seg-btn, .op-tabs > .cx, .ls-tab) { font-size: var(--t-tab); }
/* Titles: cards a step under the section's hero, so the hierarchy reads. */
body.op-readable :is(.tcard h2, .tcard h3.t, .d-card-head h2, .d-card-head h3) { font-size: var(--t-card); line-height: 1.2; }
body.op-readable .tcard.op-primary > :is(header, .thead) h2 { font-size: clamp(22px, 1.9vw, 27px); }
body.op-readable .tcard.op-secondary > :is(header, .thead) h2 { font-size: var(--t-card-sm); }
body.op-readable .op-title { font-size: clamp(38px, 4.4vw, 64px); }
body.op-readable .op-kick { font-size: 14.5px; }
body.op-readable :is(.side-nav .grp, .v-side-nav .grp, .dk-pal-group) { font-size: 14px; }
body.op-readable .side-note .v-plancard-t { font-size: 15.5px; }
/* Rows, the sidebar and the sheet's small parts: readable, not tiny. */
body.op-readable :is(.row small, .vp-todo small, .kpi .k, .kpi .d, .v-place-card-state, .v-place-state, .side-place small) { font-size: 15px; }
body.op-readable :is(.side-nav a, .side-nav button, .v-side-item) { font-size: 16.5px; }
body.op-readable :is(.pill, .tag, .d-needs, .v-side-tag, .v-side-count) { font-size: 14px; }
body.op-readable .vp-state .v-state-word, body.op-readable .vp-state.v-state.cut .v-state-word { height: 27px; font-size: 14px; }
body.op-readable .op-hero-tag .plate.sm { font-size: 14px; }
body.op-readable .vp-sign-span { font-size: 15px; }
body.op-readable .tabbar :is(a, button) { font-size: 13.5px; }
/* Fine print, and only fine print: the footer, timestamps, the map's credit, a key hint. */
body.op-readable :is(.legal-links, .legal-links a, .v-updated, .vp-said-item .top small, .d-map-credit, .pp-foot, .vp-sign-keys, kbd) { font-size: var(--t-fine); }

/* ── Hero ── */
.op-hero { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px clamp(20px, 3vw, 48px); align-items: end; margin: 4px 0 clamp(20px, 2.4vw, 32px); }
.op-hero-copy { min-width: 0; }
.op-kick { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 10px; font-size: 13px; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; color: var(--ink3); }
.op-kick .no { display: inline-grid; place-items: center; min-width: 28px; height: 22px; padding: 0 8px; border-radius: 99px; background: var(--ink); color: var(--ground); font-size: 11px; letter-spacing: .04em; }
.op-title { margin-top: 12px; font-weight: 800; font-size: clamp(34px, 4.2vw, 60px); line-height: .98; letter-spacing: -.042em; text-wrap: balance; }
.op-title .mk { font-style: normal; background: linear-gradient(transparent 58%, var(--mark) 58% 92%, transparent 92%); padding: 0 .04em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.op-line { margin-top: 14px; max-width: 38em; font-size: clamp(17px, 1.3vw, 19px); line-height: 1.5; color: var(--ink2); text-wrap: pretty; }
.op-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.op-hero-art { position: relative; width: clamp(200px, 22vw, 300px); aspect-ratio: 5 / 4; align-self: center; }
.op-cutout { position: absolute; inset: 0; background: center / contain no-repeat; filter: drop-shadow(0 14px 16px rgba(30,20,8,.26)); rotate: -2deg; }
.op-hero-art .art { position: absolute; width: 46%; box-shadow: var(--shadow-lift); }
.op-hero-art .art.a1 { left: 0; top: 4%; rotate: -5deg; }
.op-hero-art .art.a2 { right: 2%; bottom: 0; width: 40%; rotate: 4deg; }
.op-hero-tag { position: absolute; left: 50%; top: 50%; z-index: 2; display: grid; justify-items: start; gap: 6px; padding: 14px 16px 16px; translate: -50% -42%; min-width: 64%; }
.op-hero-tag small { font-size: 12px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; color: var(--ink3); }
.op-hero-tag b { font-weight: 800; font-size: 15px; letter-spacing: -.01em; }
@media (max-width: 720px) {
  .op-hero { grid-template-columns: minmax(0, 1fr); }
  .op-hero-art { position: absolute; right: -4px; top: -6px; width: 112px; z-index: 0; pointer-events: none; }
  .op-hero-art .op-hero-tag { display: none; }
  .op-hero-copy { position: relative; z-index: 1; }
  .op-hero-art + .op-hero-copy .op-title, .op-hero:has(.op-hero-art) .op-kick { padding-right: 104px; }
  .op-acts { margin-top: 18px; }
  .op-acts > .btn { flex: 1 1 auto; }
}

/* ── Weight ── */
.tcard.op-primary { padding: clamp(18px, 1.8vw, 28px); box-shadow: var(--shadow-lift); }
.tcard.op-primary > header h2, .tcard.op-primary > .thead h2 { font-size: clamp(22px, 1.8vw, 27px); letter-spacing: -.028em; }
.tcard.op-primary::after { content: ''; position: absolute; left: 28px; top: -10px; width: 86px; height: 22px; rotate: -4deg; background: linear-gradient(90deg, rgba(255,255,255,.2), transparent 30%, rgba(255,255,255,.14) 70%, transparent), rgba(226,214,178,.78); box-shadow: 0 1px 1px rgba(60,40,10,.12); pointer-events: none; }
.tcard.op-secondary { background: var(--ground2); box-shadow: none; }
.tcard.op-secondary > header h2, .tcard.op-secondary > .thead h2 { font-size: 17px; }
.op-label { font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--ink3); }

/* ── Paper details ── */
.op-stamp { --st: #137A48; display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 9px; border-radius: 4px 5px 3px 6px; color: var(--st); box-shadow: inset 0 0 0 2px var(--st); rotate: -2.5deg; font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; -webkit-mask: var(--stamp-grain-op) 0 0 / 120px 60px; mask: var(--stamp-grain-op) 0 0 / 120px 60px; }
.op-stamp::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.op-stamp.busy { --st: #946006; } .op-stamp.sold { --st: #AE2A31; } .op-stamp.closed { --st: var(--ink3); }
:root { --stamp-grain-op: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='60'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.55' numOctaves='2' seed='9' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 0 0 0 4.4'/%3E%3C/filter%3E%3Crect width='120' height='60' filter='url%28%23w%29'/%3E%3C/svg%3E"); }
:root[data-theme="dark"] .op-stamp:not(.cut *) { --st: var(--green-ink); }
:root[data-theme="dark"] .op-stamp.busy:not(.cut *) { --st: var(--s-busy); }
:root[data-theme="dark"] .op-stamp.sold:not(.cut *) { --st: var(--s-sold); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .op-stamp:not(.cut *) { --st: var(--green-ink); }
  :root:not([data-theme="light"]) .op-stamp.busy:not(.cut *) { --st: var(--s-busy); }
  :root:not([data-theme="light"]) .op-stamp.sold:not(.cut *) { --st: var(--s-sold); }
}
.op-taped { position: relative; }
.op-taped > .op-tape { position: absolute; left: 50%; top: -11px; z-index: 2; width: 92px; height: 24px; translate: -50% 0; rotate: -3.5deg; background: linear-gradient(90deg, rgba(255,255,255,.18), transparent 30%, rgba(255,255,255,.12) 70%, transparent), rgba(226,214,178,.72); box-shadow: 0 1px 1px rgba(60,40,10,.12); pointer-events: none; }

/* ── Empty states ── */
.op-empty { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 18px; align-items: center; padding: 18px; border-radius: 12px; background: var(--ground2); text-align: left; }
.op-empty .art { grid-row: span 3; width: 76px; border-radius: 4px; rotate: -4deg; box-shadow: var(--shadow-lift); }
.op-empty b { font-weight: 800; font-size: 17px; letter-spacing: -.01em; }
.op-empty p { color: var(--ink2); font-size: 15.5px; line-height: 1.45; }
.op-empty .op-empty-act { justify-self: start; margin-top: 4px; }
.op-empty .op-empty-act > * { max-width: 100%; height: auto; min-height: 40px; white-space: normal; }
@media (max-width: 380px) { .op-empty { gap: 8px 14px; padding: 16px 14px; } .op-empty .art { width: 58px; } }
.tcard.op-secondary .op-empty { background: var(--sheet); }

/* ── Loading ── */
.op-skel { display: block; height: 14px; border-radius: 7px; background: var(--well); position: relative; overflow: hidden; }
.op-skel + .op-skel { margin-top: 10px; }
.op-skel.lg { height: 26px; width: 60%; }
.op-skel::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--sheet) 70%, transparent), transparent); transform: translateX(-100%); animation: op-shimmer 1.3s ease-in-out infinite; }
@keyframes op-shimmer { to { transform: translateX(100%); } }

/* ── Motion ── */
[data-op-reveal] { opacity: 0; translate: 0 12px; transition: opacity 420ms var(--ease-out), translate 520ms var(--ease-out); transition-delay: calc(var(--i, 0) * 55ms); }
[data-op-reveal].is-in { opacity: 1; translate: 0 0; }
.op-press { transition: transform 160ms var(--ease-out); }
.op-press:active { transform: scale(.97); }
.op-pop { animation: op-pop 520ms var(--ease-spring); }
@keyframes op-pop { 0% { transform: scale(1); } 35% { transform: scale(1.06); } 100% { transform: scale(1); } }
.op-saved { animation: op-saved 900ms var(--ease-out); }
@keyframes op-saved { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 55%, transparent); } 100% { box-shadow: 0 0 0 14px transparent; } }

@media (prefers-reduced-motion: reduce) {
  [data-op-reveal] { opacity: 1; translate: none; transition: none; }
  .op-press:active { transform: none; }
  .op-pop, .op-saved { animation: none; }
  .op-skel::after { animation: none; }
}
