/* ACRVO design tokens — "Topaz" (ROADMAP #8): warm paper, near-black green-ink,
   deep teal primary, earth accents (terracotta / brick / sand). Galeria's bones
   survive (big type, hairlines, photo-first grid); palette + warmth shift, and
   the display voice leans into big bold Inter. UI primary = --accent (teal);
   --red stays the alert/wordmark spark. Single body+display face = Inter. */
/* Theme tokens — palette pulled from the app icon (charcoal · mauve-plum · warm sand).
   LIGHT is the default; DARK redefines only the tokens (components style THROUGH them, so
   the whole app follows). --shadow/--overlay/--scrim carry theme-aware depth so dark reads
   right. --dot = the masthead accent dot (rose, same in both modes, Matias's call). */
:root {
  --paper:#F4EEE6; --paper-2:#EAE1D5; --ink:#241F29;
  --ink-soft:#6E6674; --ink-faint:#A49CA8; --line:#DDD6D5; --line-2:#CEC5C5;
  --accent:#604775; --accent-press:#4D375F; --on-accent:#FBF7F0;
  --ok:#2F7A4F; --warn:#9A6B16; --danger:#B23A20; --red:#C0432B; --dot:#D98AA6;
  --wa:#2F7A4F;  /* WhatsApp brand affordance — a deep green (not iMessage #25D366), one
                   fixed value in BOTH themes: it's a brand mark, so it never flips. */
  --chip-ok-bg:#E4EDE1; --chip-ok-ink:#36593A;
  --chip-warn-bg:#F4E7CE; --chip-warn-ink:#8A5E14;
  --chip-alert-bg:#F2DCD5; --chip-alert-ink:#A2402C;
  --err-bg:#FBF1EE;
  --terra:#B86F3E; --brick:#A44040; --sand:#EBD9C0;
  --shadow:rgba(40,28,48,.16); --shadow-strong:rgba(40,28,48,.28);
  --overlay:rgba(30,22,36,.42); --scrim:rgba(20,16,10,.32); --hair:rgba(20,16,10,.10);
  --card:#FBF6EF;   /* a card lifted above the paper ground */
  --field:#FFFDF9;  /* an INPUT surface — brighter than --card so a form field actually
                       reads as white on the paper (s39; --card was only ~3% off) */
  /* ONE radius scale (s35 style pass) — components style THROUGH these, so the app rounds
     consistently instead of the old 2/6/8/9/10/11/12px sprawl. */
  --r-ctl:12px; --r-card:16px; --r-sheet:20px; --r-pill:999px;
  /* Editorial extensions: the ONE gradient hero card per page, and a tint for data selos. */
  --grad:linear-gradient(150deg,#705285 0%,#46335A 96%);
  --grad-ok:linear-gradient(150deg,#3E8A5E 0%,#25553A 96%);   /* the plum gradient's green twin — venda (s49) */
  --tint:rgba(96,71,117,.10); --tint-2:rgba(96,71,117,.16); --warn-tint:rgba(154,107,22,.14);
  --serif:'Inter',system-ui,sans-serif; --sans:'Inter',system-ui,sans-serif;
}
:root[data-theme="dark"] {
  --paper:#191619; --paper-2:#221E24; --ink:#ECE4DB;
  --ink-soft:#ADA3B0; --ink-faint:#7C7382; --line:#322C39; --line-2:#3E3646;
  --accent:#C2A3D6; --accent-press:#B08FC6; --on-accent:#1B1720;
  --ok:#5FBA80; --warn:#D0A54B; --danger:#E0745A; --red:#E0745A; --dot:#D98AA6;
  --chip-ok-bg:color-mix(in srgb, var(--ok) 22%, var(--card)); --chip-ok-ink:var(--ok);
  --chip-warn-bg:color-mix(in srgb, var(--warn) 22%, var(--card)); --chip-warn-ink:var(--warn);
  --chip-alert-bg:color-mix(in srgb, var(--danger) 22%, var(--card)); --chip-alert-ink:var(--danger);
  --err-bg:color-mix(in srgb, var(--danger) 15%, var(--card));
  --terra:#C98B5E; --brick:#C46A6A; --sand:#2E2833;
  --shadow:rgba(0,0,0,.4); --shadow-strong:rgba(0,0,0,.55);
  --overlay:rgba(0,0,0,.58); --scrim:rgba(0,0,0,.5); --hair:rgba(255,255,255,.09);
  --card:#221E24;
  --field:#221E24;  /* dark: fields stay at card level — no pop needed on a dark ground */
  --grad:linear-gradient(150deg,#4F3C63 0%,#302340 96%);
  --grad-ok:linear-gradient(150deg,#2F6E4A 0%,#1B3A28 96%);
  --tint:rgba(194,163,214,.14); --tint-2:rgba(194,163,214,.20); --warn-tint:rgba(208,165,75,.18);
}

* { box-sizing:border-box; margin:0; padding:0; }
html, body {
  background:var(--paper); color:var(--ink); font-family:var(--sans);
  /* Fixed-width vertical scroll only — no horizontal pan/zoom-out. A stray overflow
     anywhere is clipped instead of expanding the layout viewport (s22 device fix).
     `hidden` is the FALLBACK only: on html/body it makes the page a SCROLL CONTAINER,
     and iOS Safari then resolves position:fixed against IT instead of the viewport —
     the navbar detached and painted mid-page during momentum scroll (s24 device bug).
     `clip` clips identically WITHOUT creating a scroll container, so fixed stays
     viewport-relative. Desktop Chrome never reproduced it. */
  overflow-x:hidden;
  -webkit-tap-highlight-color:transparent;
  /* App-like: a long-press fires OUR gesture, not iOS text-select / the
     Copy·Look Up·Translate callout or the image-save menu. Re-enabled on real
     inputs just below so typing + field selection still work. */
  -webkit-user-select:none; user-select:none; -webkit-touch-callout:none;
}
@supports (overflow-x: clip) { html, body { overflow-x:clip; } }
input, textarea, select, [contenteditable="true"] { -webkit-user-select:text; user-select:text; }
img { -webkit-touch-callout:none; -webkit-user-drag:none; }
body { min-height:100vh; }

.app { max-width:480px; margin:0 auto; min-height:100vh; position:relative; background:var(--paper); }
.content { padding:8px 22px 140px; }

/* masthead */
.mast { display:flex; align-items:center; justify-content:space-between; padding:22px 2px 4px; }
.who { display:flex; align-items:center; gap:11px; }
.avatar { width:48px; height:48px; border-radius:50%; background:var(--accent); color:var(--on-accent);
  font-family:var(--serif); font-size:21px; display:grid; place-items:center; overflow:hidden; flex:none; }
.topbar .avatar:only-child { margin-left:auto; }
/* wordmark masthead — the big serif title and the avatar share the top line */
/* 14px top, not the titletop's 18 (s48, his call: y=26): this row's 42px avatar
   centers and lands the h1 4px lower than a plain title row — trimming the
   padding puts trabalhos/acervo on EXACTLY the same row as mesa/rede (h1 top 26). */
.masthead { display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:14px 2px 2px; }
.masthead h1 { font-family:var(--serif); font-weight:800; font-size:33px; letter-spacing:-.035em; margin:0; }
/* masthead room-doors — quiet glyphs to the left of the avatar (Rede, Lixeira) */
.mast-tools { display:flex; align-items:center; gap:13px; }
.masttool { color:var(--ink-faint); text-decoration:none; display:flex; flex:none;
  border:none; background:none; padding:0; cursor:pointer; -webkit-appearance:none; appearance:none; }
.masttool svg { width:23px; height:23px; stroke:currentColor; stroke-width:1.5; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.masttool:active { color:var(--accent); }
/* pink-sparkle créditos balance chip (Phase 1) — a glance meter at every AI-spend surface;
   tap opens the recarga sheet. Position is the mount's job; this is just the pill. */
.creditchip { display:inline-flex; align-items:center; align-self:center; gap:7px; flex:none;
  border:1px solid var(--line-2); background:var(--card); border-radius:var(--r-pill);
  padding:5px 13px 5px 9px; cursor:pointer; -webkit-appearance:none; appearance:none; }
/* s55 (his call): the credit pill is the BASE look-page size EVERYWHERE — the old masthead
   shrink (13px, nudged onto the title baseline) is gone. Here it keeps only an invisible
   ~44px tap target and centers in its row via the base .creditchip align-self. */
.masthead .creditchip, .mesatitle .creditchip { position:relative; }
.masthead .creditchip::before, .mesatitle .creditchip::before { content:""; position:absolute; left:0; right:0; top:-12px; bottom:-12px; }

/* THE INVITE ENVELOPE GLYPH (s54): sits with the feedback door, top-right of the rede.
   fill = a card to give · pink outline = something in flight · grey = dormant. */
.mesatitle .mastglyphs { display:flex; align-items:center; gap:6px; align-self:center; transform:translateY(6px); }   /* seat the glyphs on the title's visual line (s62) — the box-centre sat optically high above the big serif */
/* pad each glyph into a real ~39px touch target so the two don't mis-tap into each other
   (the svg alone is 23px); negative margin keeps the row visually snug to the masthead. */
.mastglyphs .masttool { padding:8px; margin:-8px 0; border-radius:50%; }
.mastglyphs .fbdoor { transform:none; }
.envglyph { position:relative; }
.envglyph svg { width:26px; height:26px; }   /* a touch bigger than the masttool 23px (s62, his call) */
.envglyph svg rect, .envglyph svg path { fill:none; stroke:currentColor; }
.envglyph.env--grey { color:var(--ink-faint); }
.envglyph.env--pink { color:var(--dot); }
.envglyph.env--fill { color:var(--ink); }
.envglyph.env--fill svg rect { fill:var(--dot); }
.envbadge { position:absolute; top:3px; right:3px; min-width:15px; height:15px; padding:0 3px;
  border-radius:8px; background:var(--accent); color:var(--on-accent); font-size:10px; font-weight:700;
  line-height:1; display:grid; place-items:center; border:1.5px solid var(--paper);
  font-variant-numeric:tabular-nums; }

/* The acceptance celebration banner (s54): a card just joined on your vouch. */
.acbanner { display:flex; align-items:center; gap:11px; margin:10px 18px 0; padding:11px 12px;
  border:1px solid var(--dot); border-radius:14px;
  background:linear-gradient(100deg, color-mix(in srgb, var(--dot) 18%, transparent), color-mix(in srgb, var(--accent) 10%, transparent)); }
.acbanner-cake { width:36px; height:36px; border-radius:50%; background:var(--dot); flex:none;
  display:grid; place-items:center; }
.acbanner-cake svg { width:20px; height:20px; fill:var(--on-accent); }
.acbanner-body { flex:1; min-width:0; text-align:left; background:none; border:0; padding:0;
  font-family:inherit; cursor:pointer; color:var(--ink); }
.acbanner-body b { display:block; font-size:14.5px; font-weight:600; }
.acbanner-body small { color:var(--ink-soft); font-size:12.5px; }
.acbanner-x { width:26px; height:26px; border-radius:50%; flex:none; background:none; border:0;
  color:var(--ink-faint); display:grid; place-items:center; cursor:pointer; }
.acbanner-x svg { width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2; }

/* Inside the invite sheet: band labels, avatars (real face for who joined, monogram for pending). */
/* Stable frame + pinned footer (s58): the panel is a flex column capped at 80vh — it sizes to
   its content when short (no wasted box), and when tall it holds the cap while the BODY scrolls
   under a Fechar that never moves. Opening the composer grows it only until the cap, then scrolls. */
.invitesheet-panel { display:flex; flex-direction:column; max-height:80vh; padding:0; overflow:hidden; }
.invitesheet-body { flex:1 1 auto; min-height:0; overflow-y:auto; padding:16px 12px 29px; }   /* 29 + 8 (foot pad-top) = the 37px card-to-card gap, so the last card clears the Fechar by the same rhythm (s66, his call) */
.invitesheet-body .pash-eye { margin-bottom:14px; }   /* breathing room above the convite card */
/* The pinned footer (s66, his call — option B): the app's canon filled Fechar (.menusheet-cancel)
   in a padded footer, KEEPING the scroll-dissolve gradient above it — a real button, not a
   buttonless bar, and the list still fades under it instead of hard-clipping a half-row. */
.invitesheet-foot { flex:none; position:relative; background:var(--paper);
  padding:8px 12px calc(2px + env(safe-area-inset-bottom)); }
.invitesheet-foot::before { content:""; position:absolute; left:0; right:0; top:-22px; height:22px;
  background:linear-gradient(to top, var(--paper), transparent); pointer-events:none; }
.invitesheet-panel .invitesheet-fechar { margin:0; }   /* canon button, no top margin in the footer */
.invitesheet-panel .invitesheet-fechar:active { background:var(--line-2); }
.invgrouplbl { display:flex; align-items:center; gap:8px; margin:16px 0 8px; font-size:11px;
  font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint); }
.invgroup-dash { width:16px; height:3px; border-radius:2px; background:var(--dot); }
.invav { width:40px; height:40px; border-radius:50%; flex:none; display:grid; place-items:center;
  overflow:hidden; font-family:var(--serif); font-weight:600; font-size:16px; }
.invav--mono { background:var(--paper-2); border:1px dashed var(--line-2); color:var(--ink-faint); }
.invav--photo { background:var(--accent); color:var(--on-accent); }
.invav--photo img { width:100%; height:100%; object-fit:cover; }
.invrow-ok { width:20px; height:20px; border-radius:50%; flex:none; background:var(--ok);
  display:grid; place-items:center; }
.invrow-ok svg { width:12px; height:12px; fill:none; stroke:var(--on-accent); stroke-width:3; }
.creditchip-num { font-family:var(--sans); font-size:15px; font-weight:600;
  line-height:1; color:var(--ink); font-variant-numeric:tabular-nums; }
/* the sparkle sits in a small tinted coin that leads the number (option D) */
.creditchip-coin { width:16px; height:16px; border-radius:50%; background:var(--tint);
  display:grid; place-items:center; flex:none; }
.creditchip-g { width:9px; height:9px; fill:var(--dot); }
.creditchip:active { background:var(--tint); }
/* Phase 3 — "getting low" (≤3): the chip turns amber so a thinning balance reads
   pre-attentively, before the binary zero-state; number + coin go warn too */
.creditchip.low { background:var(--warn-tint); border-color:var(--warn-tint); }
.creditchip.low .creditchip-num { color:var(--warn); }
.creditchip.low .creditchip-coin { background:rgba(154,107,22,.16); }
.creditchip.low .creditchip-g { fill:var(--warn); }
.creditchip.low .creditchip-g { fill:var(--warn); }
/* Phase 2 — the cost at the point of spend: a quiet hint under each generate/polir CTA
   so the decision ('can I afford this?') is answered where it's made */
.gencost { display:flex; align-items:center; justify-content:center; gap:5px; margin:8px 0 0;
  font-size:12px; color:var(--ink-soft); }
.gencost svg { width:12px; height:12px; flex:none; fill:var(--dot); }
/* topbar (piece/look detail) right cluster: balance chip beside the menu / graduation verb */
.topbar-right { display:flex; align-items:center; gap:12px; }
.who h1 { font-family:var(--serif); font-size:19px; font-weight:500; letter-spacing:.01em; line-height:1.1; }
.who .sub { font-size:11.5px; color:var(--ink-faint); letter-spacing:.02em; margin-top:2px; font-variant-numeric:tabular-nums; }
.today { font-size:12.5px; color:var(--ink-soft); padding:14px 2px 4px; letter-spacing:.01em; }
.today b { color:var(--warn); font-weight:500; }

.slabel { font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); margin:30px 2px 13px; }
.piece-detail .slabel { font-family:var(--serif); font-size:17px; font-weight:500; letter-spacing:0; text-transform:none; color:var(--ink); margin:30px 2px 12px; }

/* empty state — "first day of a new studio", not embarrassing */
.empty { text-align:center; padding:72px 24px 40px; }
.empty .glyph { width:62px; height:62px; margin:0 auto 24px; color:var(--accent); opacity:.92; }
.empty .glyph svg { width:100%; height:100%; stroke:currentColor; stroke-width:1; fill:none; }
.empty h2 { font-family:var(--serif); font-weight:500; font-size:23px; margin-bottom:11px; }
.empty p { font-size:14px; color:var(--ink-faint); max-width:288px; margin:0 auto; line-height:1.55; }
.empty .hint { margin-top:28px; font-size:12.5px; color:var(--ink-soft); display:inline-flex; align-items:center; gap:7px; }
.empty .hint svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.6; fill:none; stroke-linecap:round; }
/* s61 cold-start: the visible add door + the hold-to-add teach line on an empty acervo */
.acempty-add { width:auto; margin:20px auto 0; padding:12px 22px; }
.acempty-hint { margin-top:14px; font-size:12px; color:var(--ink-faint); display:inline-flex; align-items:center; justify-content:center; gap:5px; }
.acempty-hint svg { width:14px; height:14px; stroke:var(--accent); stroke-width:1.8; fill:none; stroke-linecap:round; vertical-align:middle; }

/* collection bodies — M2 fills these (kept so M2 adds data, not CSS) */
.cont { border-radius:var(--r-ctl); overflow:hidden; border:1px solid var(--line); cursor:pointer; }
.cont .img { aspect-ratio:16/10; display:grid; place-items:center; background:var(--paper-2); }
.cont .img svg { width:30%; height:60%; stroke:var(--ink-soft); stroke-width:1; fill:none; opacity:.6; }
.cont .meta { padding:13px 15px; background:var(--paper); }
.cont .meta h2 { font-family:var(--serif); font-size:18px; font-weight:500; }
.cont .meta p { font-size:12.5px; color:var(--ink-faint); margin-top:3px; }
.two { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.pc { cursor:pointer; }
.pc .img { aspect-ratio:2/3; border-radius:var(--r-card); border:1px solid var(--line); display:grid; place-items:center; transition:border-color .18s; overflow:hidden; }
.pc:active .img { border-color:var(--ink); }
.pc .img svg { width:52%; height:52%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.62; }
.pc .nm { font-size:13.5px; font-weight:500; margin-top:9px; }
.pc .sb { font-size:11.5px; color:var(--ink-faint); margin-top:2px; }
.redisc { display:flex; gap:15px; align-items:center; border-top:1px solid var(--line); border-bottom:1px solid var(--line); padding:16px 2px; margin-top:6px; cursor:pointer; }
.redisc .img { width:66px; aspect-ratio:2/3; border-radius:5px; background:var(--paper-2); display:grid; place-items:center; flex:none; }
.redisc .img svg { width:54%; height:54%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.6; }
.redisc h3 { font-family:var(--serif); font-size:16px; font-weight:500; }
.redisc p { font-size:12px; color:var(--ink-faint); margin-top:4px; font-style:italic; }
.allmore { display:flex; align-items:center; justify-content:center; gap:8px; margin:34px 0 10px; font-size:13px; color:var(--ink-soft); text-decoration:none; }
.allmore .n { font-variant-numeric:tabular-nums; }
.allmore svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.5; fill:none; }

/* dock — bottom bar + sparkle + talk sheet, fixed to the phone column */
.dock { position:fixed; left:50%; transform:translateX(-50%); bottom:0; width:100%; max-width:480px; pointer-events:none; z-index:20; }
.bar { pointer-events:auto; position:absolute; left:0; right:0; bottom:0; height:80px; background:rgba(255,255,255,.92);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); border-top:1px solid var(--line);
  display:flex; align-items:center; justify-content:space-around; padding:0 28px 16px; }
.tab { display:flex; flex-direction:column; align-items:center; gap:5px; font-size:10.5px; letter-spacing:.03em;
  color:var(--ink-faint); background:none; border:none; cursor:pointer; text-decoration:none; }
.tab svg { width:22px; height:22px; stroke:currentColor; stroke-width:1.4; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.tab.on { color:var(--ink); }
.add { pointer-events:auto; width:54px; height:54px; border-radius:50%; background:var(--accent); color:var(--on-accent);
  display:grid; place-items:center; margin-top:-22px; cursor:pointer; border:none; transition:transform .15s; }
.add:active { transform:scale(.94); }
.add svg { width:24px; height:24px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; }
.spark { pointer-events:auto; position:absolute; right:18px; bottom:98px; width:52px; height:52px; border-radius:50%;
  background:var(--paper); border:1px solid var(--accent); display:grid; place-items:center; cursor:pointer; transition:transform .15s; }
.spark:active { transform:scale(.94); }
.spark svg { width:24px; height:24px; stroke:var(--accent); stroke-width:1.3; fill:none; stroke-linecap:round; stroke-linejoin:round; }

/* talk sheet */
.scrim { pointer-events:none; position:absolute; inset:0; background:rgba(20,20,20,.38); opacity:0; transition:opacity .25s; }
.scrim.on { pointer-events:auto; opacity:1; }
.sheet { pointer-events:auto; position:absolute; left:0; right:0; bottom:0; background:var(--paper);
  border-radius:22px 22px 0 0; padding:12px 22px 30px; transform:translateY(110%);
  transition:transform .3s cubic-bezier(.2,.8,.2,1); }
.sheet.on { transform:translateY(0); }
.handle { width:40px; height:4px; border-radius:3px; background:var(--line-2); margin:0 auto 18px; }
.sheet h4 { font-family:var(--serif); font-size:18px; font-weight:500; margin-bottom:4px; }
.sheet .hint { font-size:12.5px; color:var(--ink-faint); margin-bottom:18px; }
.microw { display:flex; align-items:center; gap:13px; border:1px solid var(--line-2); border-radius:999px; padding:11px 16px; margin-bottom:16px; }
.microw .mic { width:34px; height:34px; border-radius:50%; background:var(--accent); display:grid; place-items:center; flex:none; }
.microw .mic svg { width:17px; height:17px; stroke:var(--on-accent); stroke-width:1.5; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.microw span { font-size:13px; color:var(--ink-faint); }
.exs { display:flex; flex-direction:column; gap:9px; }
.ex { font-size:13px; color:var(--ink-soft); border:1px solid var(--line); border-radius:10px; padding:11px 14px; cursor:pointer; }
.ex:active { border-color:var(--ink); }

.svg-defs { position:absolute; width:0; height:0; }

/* ---- M2a: collection, detail, form ---- */

/* images fill their framed boxes */
.pc .img img, .tile .img img, .hero img, .thumb img, .photo-grid img { width:100%; height:100%; object-fit:cover; display:block; }
.pc .img, .tile .img { overflow:hidden; }
.pc { text-decoration:none; color:inherit; }
a.allmore { text-decoration:none; }
a.tab, a.add { text-decoration:none; }

/* top bar (back / title / action) */
.topbar { display:flex; align-items:center; justify-content:space-between; padding:18px 2px 6px; min-height:32px; }
.topbar .back { display:flex; align-items:center; gap:6px; font-size:13px; color:var(--ink-soft); text-decoration:none; }
.topbar .back svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.5; fill:none; }
.topbar .ttl { font-family:var(--serif); font-size:16px; font-weight:500; }
.topbar .sp { width:54px; }
.iconbtn { display:grid; place-items:center; width:34px; height:34px; border-radius:50%; color:var(--accent); text-decoration:none; }
.iconbtn svg { width:21px; height:21px; stroke:currentColor; stroke-width:1.6; fill:none; stroke-linecap:round; }

/* archive title + identity mirror */
.title { padding:8px 2px 0; }
.title h1 { font-family:var(--serif); font-size:30px; font-weight:500; letter-spacing:.01em; }
.mirror { font-size:12.5px; color:var(--ink-faint); font-style:italic; line-height:1.5; margin-top:9px; display:flex; gap:8px; align-items:flex-start; }
.mirror svg { width:14px; height:14px; stroke:var(--accent); stroke-width:1.3; fill:none; flex:none; margin-top:2px; }

/* lenses */
.lenses { display:flex; gap:20px; padding:18px 2px 0; border-bottom:1px solid var(--line); margin-bottom:18px; }
.lens { font-size:13px; letter-spacing:.02em; color:var(--ink-faint); padding-bottom:12px; position:relative; cursor:pointer; white-space:nowrap; background:none; border:none; }
.lens.on { color:var(--ink); }
.lens.on::after { content:""; position:absolute; left:0; right:0; bottom:-1px; height:2px; background:var(--accent); }

/* grid + tiles */
.grp { font-size:11px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-faint); margin:22px 0 13px; }
.grp:first-child { margin-top:0; }
.grid { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-bottom:8px; }
/* grid items default to min-width:auto, so a nowrap caption (a long owner name like
   "VANESSA MARTINEZ" on a rede-band tile) sets a min-content width WIDER than its 1fr
   share — the second column then overflows the band and drags the page offscreen right
   (s62). min-width:0 lets 1fr shrink so the caption's own ellipsis truncates instead. */
.grid > * { min-width:0; }
.tile { cursor:pointer; display:flex; flex-direction:column; gap:9px; text-decoration:none; color:inherit; }
.tile .img { aspect-ratio:2/3; border-radius:var(--r-card); border:1px solid var(--line); display:grid; place-items:center; background:var(--paper-2); overflow:hidden; }
/* s65 (his call): a navigating tap needs no feedback — the page changing IS the feedback. No
   active border, outline, or darken on a tile link (that flash read as a stray "frame"). */
/* meu acervo (s41, his pick): the picker's card idiom — the whole tile is ONE lifted
   card (photo on top, a caption footer under it), not a bare photo. What the photo
   can't say rides the footer: SIZE (own) or SIZE · owner (rede band). Scoped to
   .acervo so other tile grids (mesa board, trash, project) keep their look; tap sinks
   the card. */
.acervo .tile { background:var(--card); border-radius:var(--r-card); overflow:hidden; gap:0;
  box-shadow:0 8px 22px var(--shadow-strong); transition:box-shadow .18s, transform .18s; }
.acervo .tile:active { box-shadow:0 3px 10px var(--shadow); }
.acervo .tile .img { border:none; border-radius:0; background:var(--card); box-shadow:none; }
.acervo .tile .sb { text-align:center; padding:7px 8px 8px; font-size:11.5px; color:var(--ink-faint);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.acervo .tile .nm { text-align:center; padding:7px 8px 0; }
.tile .img svg { width:50%; height:50%; stroke:var(--ink-soft); stroke-width:1.05; fill:none; opacity:.6; }
.tile .nm { font-size:13px; font-weight:500; line-height:1.25; }
.tile .sb { font-size:11px; color:var(--ink-faint); }

/* piece detail */
/* every piece-photo box in the app is 3:4 — the hero included, so one framing
   (focal + zoom) reads identically everywhere (no per-window drift) */
.hero { position:relative; aspect-ratio:2/3; border-radius:var(--r-ctl); border:1px solid var(--line); display:grid; place-items:center; background:var(--paper-2); margin-top:6px; overflow:hidden; }
.hero svg { width:42%; height:42%; stroke:var(--ink-soft); stroke-width:.9; fill:none; opacity:.6; }
.hero.zoomable { cursor:zoom-in; }
/* s77 (his 'Option 2'): the AI-polish trigger is a slim button BELOW the hero (not a disc over
   it) — outlined, plum label, the app's PINK sparkle (--dot). Keeps id=heroSpark so the busy
   poller + panel wiring are untouched. */
.heropolish { width:100%; margin:14px 0 12px; display:inline-flex; align-items:center; justify-content:center; gap:7px;
  border:1px solid var(--line-2); border-radius:12px; padding:11px; background:var(--card); color:var(--accent);
  font-family:var(--sans); font-size:13.5px; font-weight:600; cursor:pointer; -webkit-tap-highlight-color:transparent; }
/* s78 (his call): optically centre the label — the ✦+gap sit left of the text, so the
   geometrically-centred group reads right-heavy. A -16px pull shifts the group left ~8px so
   the text lands visually centred (same fix as the mesa's .lineup-provar-spark). */
.heropolish-spark { width:16px; height:16px; margin-left:-16px; fill:var(--dot); stroke:none; }
.heropolish[hidden] { display:none; }   /* the class display:inline-flex would otherwise beat the UA [hidden] */
.heroshare { position:absolute; right:12px; top:12px; z-index:3; width:42px; height:42px; border:none; padding:0;
  border-radius:50%; display:grid; place-items:center; cursor:pointer; background:var(--paper); color:var(--ink);
  box-shadow:0 2px 10px rgba(20,16,10,.28); -webkit-tap-highlight-color:transparent; }
.heroshare[hidden] { display:none; }
.heroshare svg { width:20px; height:20px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.heroshare:active { transform:scale(.93); }
.heropolish:active { transform:scale(.99); }
/* s74 — disc state A: while the inline polish panel is open, the ✦ fills plum (the app's
   selected idiom), distinct from idle (paper) and generating (.busy grey). Defined BEFORE
   .busy so the generating grey wins if both ever coexist. */
.heropolish.open { background:var(--accent); color:var(--on-accent); border-color:var(--accent); }
.heropolish.open .heropolish-spark { fill:var(--on-accent); }
/* tile share (v1.0): the same Enviar affordance on a board tile — a look's AI render.
   Bottom-LEFT, because the tile's top-right corner already belongs to the × remove. */
/* Enviar sits TOP-RIGHT on every surface (s25) — same corner as the ficha's
   .heroshare, so the gesture is in one place app-wide. It used to sit bottom-left,
   where it collided with the card's own caption. On a card that already owns that
   corner with a delete × (.bx, the look page's renders), the glyph steps left of it. */
.tileshare { position:absolute; right:7px; top:7px; z-index:3; width:32px; height:32px; border:none; padding:0;
  border-radius:50%; display:grid; place-items:center; cursor:pointer; background:var(--paper); color:var(--ink);
  box-shadow:0 2px 8px rgba(20,16,10,.26); -webkit-tap-highlight-color:transparent; }
.bcard:has(.bx) .tileshare { right:39px; }
.tileshare[hidden] { display:none; }
.tileshare svg { width:16px; height:16px; stroke:currentColor; stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* Prova verbs (s37): choose the cover · reseed the look's pieces from a prova. */
.renderacts { display:flex; gap:6px; margin-top:6px; }
.renderacts[hidden] { display:none; }   /* author display:flex overrides the hidden attr's UA display:none — restore it */
/* s75 (his call): the Ajustar prova field's placeholder matches the AI-polish field (13px, not 16). */
#laCorrection::placeholder { font-size:13px; }
/* s75 (his call): typed/transcribed text 13px too, so the box reads at one size (like #personInput).
   Safe under 16px because the viewport caps zoom (maximum-scale=1). */
#laCorrection { font-size:13px; }
/* s75 (his call): the Descrever/Instruções-extras field placeholder matches Ajustar prova (13px). */
#personInput::placeholder { font-size:13px; }
/* s75 (his call): the typed/transcribed text matches too — the whole box reads at one 13px size
   (hint · beat · text). Safe under 16px because the viewport caps zoom (maximum-scale=1). */
#personInput { font-size:13px; }
/* s76 (his call): the AI-polish note reads at ONE 13px size too — typed text, dictated text and
   the transcrevendo beat all match the placeholder and the look/mesa fields (was 16px typed).
   Safe under 16px because the viewport caps zoom (maximum-scale=1). */
#polishNote { font-size:13px; }
/* s77 (his call): the look's Refazer/Ajustar card gets a symmetric corner inset — its
   Cancelar sits the same 14px from the card's bottom as from its sides (the shared
   .polishpanel bakes a 16px bottom; scoped here so the piece-detail polish panel is untouched). */
#lookArrumar { padding-bottom:14px; }
/* s75 (his call): in the Provar de novo picker the '3 créditos' line sits centred between Gerar
   and Cancelar (was hugging Cancelar) — equal gaps above and below. */
#lookProvarPanel .gencost { margin-top:5px; }
/* s75 (his call): match the Ajustar-prova panel's button→créditos→Cancelar spacing to the
   picker above — balanced 14/14 (was 8 above the créditos, 6 below). */
#lookArrumar .gencost { margin-top:14px; }
/* s75 (his call): the look-panel button stack reads as one height. Match 'Gerar imagem do
   look' and both Cancelars to 'Refazer com ajuste' (.revrefine: 12px pad + 14px font + 1px
   border = 43px). The generate submit out-specifies its .tryonform rule from here; the
   Cancelars carry a transparent 1px border so their box equals the bordered twins. */
#lookProvarPanel .tryonform button[type="submit"] { padding-top:12px; padding-bottom:12px; font-size:14px; font-weight:600; }
/* Mesa provar panel: same balanced rhythm — Gerar → 14 → créditos → 14 → Cancelar. */
#provarPanel .gencost { margin-top:14px; }
/* s77: match the Cancelar's gap to the Salvar-look button's own top gap (the input→button
   10px), so the panel's three stacked controls breathe evenly. */
#salvarPanel .menusheet-cancel { margin-top:10px; }
/* s75: the provar panel is its own action — while it's open the lineupbar (Salvar/Orçamento
   + the door) hides; the panel's own Cancelar is the sole closer, like the looks-page panels. */
/* s77: a panel open (provar OR salvar) hides only the TOGGLE ROW — the eyebrow title stays
   put and the composer opens directly under it; each panel carries its own Cancelar. */
body.provaring .lineupacts { display:none; }
.lineupacts { flex:0 0 100%; display:flex; gap:8px; align-items:stretch; }
.renderacts form { flex:1; display:flex; margin:0; }
.renderact { width:100%; display:inline-flex; align-items:center; justify-content:center; gap:5px;
  border:1px solid var(--line-2); background:var(--paper); color:var(--ink-soft);
  border-radius:8px; padding:6px 8px; font-size:11.5px; font-weight:600; line-height:1; cursor:pointer;
  -webkit-tap-highlight-color:transparent; }
.renderact svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.renderact.capa.on { background:var(--accent); border-color:var(--accent); color:#fff; }
.renderact.capa.on svg { fill:currentColor; stroke:none; }
.tileshare:active { transform:scale(.92); }
/* Meus looks (v1.0): the Mesa's collection grid. A look card is taller than a piece
   tile because its face is usually a PERSON wearing the outfit, not a flat garment. */
/* The look card keeps the app-standard 2:3 tile box (inherited from .tile .img).
   It was 3/4 — the ONE box in the app that didn't match the 2:3 the image pipeline
   standardizes on (catalog renders are 400x600), so every cover was force-cropped
   11% vertically regardless of focal. Box matches pipeline → zero crop (s25). */
.lookgrid .lookcard .nm { font-weight:500; }
/* s44: the "worked" signal lives in the subline (· N provas · enviado), never a cover
   badge — the ranking floats worked looks up; the card face stays clean (his call). */
/* "ver todos" — the Mesa shows the ripe head; the full searchable set lives at /looks. */
.lookmore-all { display:block; text-align:center; margin:14px 0 2px; font-size:13px;
  color:var(--accent); text-decoration:none; }
/* /looks screen: the search box + match line (the hoarder finds by searching, never filing). */
.looksearch { display:flex; align-items:center; gap:9px; margin:16px 0 8px; padding:10px 13px;
  border:1px solid var(--line-2); border-radius:12px; background:var(--card); }
.looksearch svg { width:17px; height:17px; stroke:var(--ink-faint); fill:none; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round; flex:none; }
.looksearch input { flex:1; min-width:0; border:none; background:none; outline:none;
  font-family:var(--sans); font-size:15px; color:var(--ink); -webkit-appearance:none; appearance:none; }
.looksmatch { font-size:12px; color:var(--ink-faint); margin:0 2px 14px; }
/* ── The LOOKBOOKS room + composer (s45/s45b, [[lookbook-grouping-arc]]) ────────
   /lookbooks is the books' own room ('meus lookbooks.'): a 2-col grid of book cards,
   each wearing its opening look's face, plus the dashed novo door — which opens /looks
   in SELECT MODE (tap order = book order). Hold a card to delete. */
.bookroom { display:grid; grid-template-columns:1fr 1fr; gap:16px 10px; margin-top:16px; }
.bookshelf-card { display:flex; flex-direction:column; gap:4px;
  text-decoration:none; color:var(--ink); }
.bookshelf-face { display:block; width:100%; aspect-ratio:3/4; border-radius:10px;
  overflow:hidden; background:var(--paper-2); border:1px solid var(--line); }
.bookshelf-face img { width:100%; height:100%; object-fit:cover; display:block; }
.bookshelf-nm { font-size:13px; font-weight:500; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; }
.bookshelf-n { font-size:11px; color:var(--ink-faint); }
.bookshelf-new { display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:7px; aspect-ratio:3/4; border:1.5px dashed var(--line-2); border-radius:10px;
  background:none; color:var(--accent); font-family:var(--sans); font-size:12px;
  text-decoration:none; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.bookshelf-new svg { width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
/* select mode: the picked cards wear an accent ring + their ORDER number */
body.bookpicking .lookgrid .lookcard { pointer-events:auto; }
.tilewrap.selpick .tile .img, .tilewrap.selpick .lookcover { outline:2.5px solid var(--accent);
  outline-offset:-2.5px; border-radius:var(--r-ctl); }
.selnum { position:absolute; top:6px; left:6px; width:22px; height:22px; display:grid;
  place-items:center; border-radius:50%; background:var(--accent); color:var(--on-accent);
  font-size:12px; font-weight:700; z-index:3; pointer-events:none; }
.bookbar { position:fixed; left:0; right:0; bottom:0; z-index:60; display:flex; align-items:center;
  gap:12px; padding:12px 16px calc(12px + env(safe-area-inset-bottom)); background:var(--card);
  border-top:1px solid var(--line); }
.bookbar[hidden] { display:none; }
.bookbar-n { font-size:13px; color:var(--ink-soft); }
.bookbar-cancel { margin-left:auto; border:none; background:none; font-family:var(--sans);
  font-size:14px; color:var(--ink-soft); cursor:pointer; }
.bookbar-go { border:none; border-radius:11px; padding:11px 18px; background:var(--accent);
  color:var(--on-accent); font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.bookbar-go:disabled { opacity:.45; }
/* the lookbook entity page: member cards + the 'pra quem?' field (no drag-reorder —
   tap order at creation is the sequence; a touch-action claim here made the page
   unscrollable, s45) */
.bookgrid .booksec { width:100%; margin-top:6px; border:none; border-bottom:1px dashed var(--line-2);
  background:none; padding:3px 1px 5px; font-family:var(--sans); font-size:12.5px; color:var(--ink);
  outline:none; -webkit-appearance:none; appearance:none; }
.bookgrid .booksec::placeholder { color:var(--ink-faint); }
.bookgrid .booksec:focus { border-bottom-color:var(--accent); border-bottom-style:solid; }
.bookadd { display:block; margin:14px 2px 0; font-size:13.5px; color:var(--accent);
  text-decoration:none; }
/* live section-heading preview on the entity grid (s45c): the same run-grouping the
   book prints, so the seção field explains itself by consequence */
.booksechead { grid-column:1 / -1; display:flex; align-items:center; gap:8px; margin:6px 0 -4px;
  font-size:11px; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  color:var(--accent); }
/* rede reachability ask (v1.0) — an unanswered prerequisite, not a dismissable nudge */
.redegate { display:flex; align-items:center; gap:11px; margin:14px 0 4px; padding:13px 14px;
  border:1px solid var(--accent); border-radius:12px; background:var(--paper-2); color:var(--ink); text-decoration:none; }
.redegate-ic svg { width:22px; height:22px; stroke:var(--accent); stroke-width:1.6; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.redegate-body { flex:1; font-size:13px; line-height:1.45; }
.redegate-body b { font-weight:600; }
.redegate-chev { width:18px; height:18px; stroke:var(--ink-faint); stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* rede price (v1.0): the number a borrower needs BEFORE she asks. On the piece page it
   sits under the name; on a storefront tile it rides the bottom edge, legible over any
   photo. Money belongs in the room where the decision is money — not on the Mesa. */
.redeprice { text-align:center; font-size:15px; font-weight:600; color:var(--ink); margin-top:6px; }
.vcell { position:relative; }
/* Size on the grid (s33 S/N): a QUIET watermark — small white text on a faint dark scrim
   floor, so it stays legible over ANY photo (a bare watermark washes out on the pale /
   studio backdrops costumes usually sit on) while receding behind the garment. Size
   SCREENS — a costume that won't fit is a dead lead — so it earns the grid; price does
   NOT ride the grid, it's a decision-time detail inside the piece card. */
.vsize { position:absolute; left:5px; top:5px; padding:1px 6px; border-radius:5px;
  font-size:10px; font-weight:600; color:#fff; letter-spacing:.03em; pointer-events:none;
  background:rgba(20,16,10,.34); -webkit-backdrop-filter:blur(1px); backdrop-filter:blur(1px); }
/* Fit block on the rede piece detail: size prominent, tape measurements below. */
.redefit { text-align:center; margin:12px 0 2px; }
.redesize { display:inline-block; font-size:15px; font-weight:700; color:var(--ink);
  background:var(--paper-2); border-radius:20px; padding:4px 13px; }
.redemeasures { display:block; margin-top:8px; font-size:12.5px; color:var(--ink-soft); }

/* ── Rede piece → pedir (s41 S/N rework) ─────────────────────────────────────
   Two zones: a tight identity header where PRICE leads, then one lifted card that
   reads as "your request". The old page stacked identity + form as one centred
   column with equal weight — no grouping told the eye where the ask began. */
.redepage .title h1 { font-size:25px; font-weight:500; letter-spacing:-.02em; line-height:1.14; text-align:center; }
/* the pedido's public card (s49): the eyebrow centred, the sentence steps down for long acervo names */
.pedpub-eye { justify-content:center; margin:0 0 6px; }
.redepage .title h1.pedpub-h1 { text-wrap:balance; }
.redepage .title h1.pedpub-h1.long { font-size:21px; line-height:1.2; }
.redeprice2 { display:flex; align-items:baseline; justify-content:center; gap:7px; margin:14px 0 3px; }
.redeprice2 b { font-size:26px; font-weight:600; letter-spacing:-.02em; color:var(--ink); }
.redeprice2 span { font-size:14px; color:var(--ink-soft); }
.redeprice2-tbc { font-size:19px !important; }
.redepage .redeowner { margin:0 0 4px; font-size:13px; }
.redepage .redefit { margin-top:14px; }

.pedircard { background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
  padding:14px 14px 16px; box-shadow:0 8px 22px rgba(40,28,48,.10); margin-top:18px; }
.pedirsec-lbl { display:flex; align-items:center; gap:7px; font-size:11px; font-weight:600;
  letter-spacing:.09em; text-transform:uppercase; color:var(--ink-soft); margin-bottom:12px; }
.pedirsec-lbl .dot { width:6px; height:6px; border-radius:50%; background:var(--dot); flex:none; }
.pedircard .pedirwhen { margin:0 0 11px; }
.pedircard .pedirjob { margin:0 0 11px; padding-right:38px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A49CA8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 13px center; background-size:16px; }
.pedircard .pedirnote { margin:0 0 14px; }
.pedircard .redewa { max-width:none; margin:0; }
.testeopt--foot { margin:12px 2px 0; }
.testeopt--foot span { font-size:12px; color:var(--ink-faint); }
.testeopt--foot em { color:var(--ink-faint); }
.btn.ghost.pilelink { max-width:none; border:none; background:none; color:var(--accent);
  font-weight:500; margin-top:8px; }
.btn.ghost.pilelink:active { border:none; color:var(--accent-press); }

/* ── Owner rental page, sectioned (s41) ──────────────────────────────────────
   The page stopped being an hr-sliced column of floating rows: an identity masthead,
   then lifted cards (deal · contato · despesas · documento), then ONE primary action.
   Reuses the card shell + rose-tick eyebrow the rede-pedir/borrower pages speak. */
.rdetail .rcard { background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-card); padding:13px 14px;
  box-shadow:0 1px 2px rgba(60,50,35,.04), 0 12px 26px -16px rgba(60,50,35,.16);
  margin-top:14px; }
.rdetail .rcard > .mesasec-lbl:first-child,
.rdetail .rcard > .pedirsec-lbl:first-child { margin-top:0; }
.rdetail .rcard.riwa { margin:14px 0 0; }
.rdetail .rcardflush { padding:2px 14px; }
/* the deal card's money folds in under an inner divider (no more mid-document hr) */
.rdeal .meta { border-top:1px solid var(--line); margin-top:12px; padding-top:12px; }
.rdeal .ripick { margin:12px 0 2px; }
/* the pedido's counter — a quiet link at the card foot, never a co-equal button */
.rcounter { text-align:right; margin-top:9px; }
.rcounter-link { display:inline-flex; align-items:center; gap:3px; font-size:12.5px;
  color:var(--accent); text-decoration:none; font-weight:500; }
.rcounter-link svg { width:14px; height:14px; stroke:currentColor; stroke-width:2;
  fill:none; stroke-linecap:round; stroke-linejoin:round; }
.rhint { font-size:11.5px; color:var(--ink-faint); line-height:1.5; margin:9px 2px 0; }
.rwait { margin-top:16px; }
.rdoc { display:flex; flex-direction:column; gap:10px; }
.rdoc .sigsend, .rdoc .siglink, .rdoc .btn.contract { margin:0; }
/* Job page cards (s41): the nota-fiscal disclosure sits under the Produção fields; the
   verba rows flow borderless and Restante alone gets an inner divider as the bottom
   line (the .row idiom's per-row borders would otherwise double it under the eyebrow). */
.rdetail .jobfiscal { margin-top:14px; }
.jobverba .row { border:none; padding:9px 0; }
.jobverba .jobrestante { border-top:1px solid var(--line); margin-top:3px; padding-top:11px; }
/* pedido: quando (v1.0) */
.pedirwhen { display:flex; gap:9px; margin:14px 0 12px; }
.pedirwhen .datefld { flex:1; }
/* The look card's face (P4): ripened render OR the combination collage. Children
   ABSOLUTE-FILL the frame: .tile .img out-specifies .lookcover (its display/
   place-items always win), so any %-height child of a content-sized wrapper is
   circular and collapses to 0 — absolute against the aspect-ratio frame is the
   one geometry that resolves under every host (.tile .img, .rthumb, .pickimg). */
.lookcover { padding:0; overflow:hidden; position:relative; }
.lookcover > img, .lookcover > .lookcover-grid, .lookcover > .lookcell-empty {
  position:absolute; inset:0; width:100%; height:100%; }
.lookcover > img { object-fit:cover; display:block; }
.rthumb .lookcover, .pickimg .lookcover { width:100%; height:100%; }
.lookstripe { display:flex; width:100%; height:10px; margin:11px 0 2px; border-radius:3px; overflow:hidden;
  border:1px solid rgba(0,0,0,.10); }  /* the look's colour signature as a title UNDERLINE (s35b), tucked
                                          under the name — substantial enough to READ as a colour meter,
                                          not a hairline decoration (s35b polish 2: thin straddled the line) */
[data-theme="dark"] .lookstripe { border-color:rgba(255,255,255,.14); }  /* mirror: dark tones on dark paper */
.lookstripe i { flex:1 1 0; }
/* s79: a hairline between swatches so a white/cream one doesn't dissolve into a light neighbour */
.lookstripe i + i { box-shadow:inset 1px 0 0 rgba(0,0,0,.09); }
[data-theme="dark"] .lookstripe i + i { box-shadow:inset 1px 0 0 rgba(255,255,255,.12); }
.lookcover-grid { display:grid; grid-template-columns:1fr 1fr; grid-auto-rows:1fr;
  gap:1px; background:var(--line); }
/* 3-piece collage: the odd last cell spans both columns (two over one) instead of
   leaving a grey quadrant hole (s35). Only 3 triggers it — the collage caps at 4. */
.lookcover-grid .lookcell:last-child:nth-child(odd) { grid-column:1 / -1; }
.lookcell { display:block; overflow:hidden; background:var(--paper-2); position:relative; }
.lookcell img { width:100%; height:100%; object-fit:cover; display:block; }
.lookcell-empty { display:grid; place-items:center; background:var(--paper-2); }
.lookcell-empty svg { width:42%; height:42%; stroke:var(--ink-faint); stroke-width:1; fill:none; opacity:.55; }
.lookmore { position:absolute; right:6px; bottom:6px; z-index:1; background:rgba(20,16,10,.75);
  color:#fff; font-family:var(--sans); font-size:11px; font-weight:600; padding:3px 8px; border-radius:999px; }

/* The naming moment (s59, Path 2): the sheet that names the look BEFORE the render — no
   in-sheet spinner (nothing generates until it's confirmed). */
.namesheet-panel { display:flex; flex-direction:column; gap:12px; padding:18px 16px calc(22px + env(safe-area-inset-bottom)); }
.namesheet-q { font-family:var(--serif); font-size:19px; font-weight:500; color:var(--ink); }
#nameSheetInput { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:16px;
  padding:12px 13px; border:1px solid var(--line-2); border-radius:10px; background:var(--paper); color:var(--ink); }
#nameSheetInput:focus { outline:none; border-color:var(--accent); }
.namesheet-acts { display:flex; gap:10px; }
.namesheet-acts button { flex:1; padding:13px; border-radius:12px; font-family:var(--sans);
  font-size:15px; font-weight:600; cursor:pointer; }
.namesheet-skip { border:1px solid var(--line-2); background:none; color:var(--ink-soft); }
.namesheet-go { border:none; background:var(--accent); color:#fff; }

/* Titles NEVER crop (s26): the inline-editable titles were single-line <input>s, which
   cannot wrap — long names clipped at the box edge on the look, produção, troca and
   ficha pages. They are auto-growing textareas now (.qedit was already textarea-ready:
   font, resize:none, overflow:hidden; app.js grows every textarea on input/load). */

/* D1 — the swatch lock made visible: one quiet line under the chips, and the door
   back to automatic. A <button> at text weight; the underline carries the action. */
.swlock { display:inline-flex; align-items:center; min-height:44px; border:none;
  background:none; padding:0 2px; margin-top:-6px; cursor:pointer;
  font-family:var(--sans); font-size:12px; color:var(--ink-faint); }
.swlock u { text-decoration-color:var(--accent); text-underline-offset:2px; margin-left:3px; }
/* D2 — the COR row's names carry their bucket's hue, so the words visibly belong to
   the chips above instead of reading as an unrelated field. */
.cdot { display:inline-block; width:10px; height:10px; border-radius:50%;
  margin-right:6px; vertical-align:-1px; border:1px solid rgba(0,0,0,.15); }

/* The widening gate (C): one quiet line under the ringed colour swatch. An offer, not
   a toggle — it only exists while a colour is picked and something would widen. */
/* min-height, not padding arithmetic: 14px padding computed to 43.99 and missed the
   44px touch minimum by a hundredth of a pixel. */
.alsolink { display:inline-flex; align-items:center; min-height:44px; margin:0 2px;
  font-family:var(--sans); font-size:13px; color:var(--ink-soft);
  text-decoration:none; padding:0 6px; }
/* The precificar offer (pricing arc phase 1) — same quiet-line idiom as .alsolink:
   an offer, not a form; it names the state and holds the door to the wall list. */
.pricelink { display:inline-flex; align-items:center; min-height:44px; margin:0 2px;
  font-family:var(--sans); font-size:13px; color:var(--ink-soft);
  text-decoration:none; padding:0 6px; }
.pricelink:active { color:var(--accent); }
.pricelink-txt a { color:inherit; text-decoration:none; }
.pricelink-txt a:active { color:var(--accent); }
/* NUDGE PILLS (s70, his call): the acervo's line-with-a-door as thin clearable chips — the count
   pill is the filter (on = filled + ×), the door pill opens a list. Same family as .ondefica-chip. */
.nudgepills { display:flex; flex-wrap:wrap; gap:8px; margin:6px 2px 4px; }
.npill { display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 10px; border:1px solid var(--line-2);
  border-radius:var(--r-pill); background:var(--card); color:var(--ink-soft); font-family:var(--sans); font-size:13px;
  text-decoration:none; white-space:nowrap; -webkit-tap-highlight-color:transparent; }
.npill svg { width:14px; height:14px; flex:none; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.npill:active { color:var(--accent); border-color:var(--accent); }
.npill.door { color:var(--accent); }
.npill.door .npill-chev { width:13px; height:13px; margin:0 -4px 0 -2px; }
.npill.on { background:var(--tint); color:var(--accent); border-color:var(--accent); padding-right:7px; }
.npill-x { display:inline-flex; align-items:center; align-self:stretch; font-size:15px; line-height:1; margin-left:2px; }
.alsolink:active { color:var(--accent); }
.alsolink.on { color:var(--ink-faint); }
/* the é/tem colour-scope control was PARKED (s62) — its .colorseg styles removed with the UI;
   the widening plumbing (tem=1 + the "tem …" grid) stays. See docs/color-widening-parked.md. */
.alsohead { margin:22px 2px 8px; font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-faint); border-top:0.5px solid var(--line); padding-top:12px; }
.alsohead span { color:var(--ink-soft); }

/* the ping card on Alugadas — the pedido just sent, with its two ways out */
.novoping { margin:14px 0 6px; padding:14px; border:1px solid var(--accent); border-radius:12px; background:var(--paper-2); }
.novoping b { display:block; font-size:14px; margin-bottom:3px; }
.novoping small { display:block; font-size:12.5px; color:var(--ink-soft); line-height:1.45; }
.novoping-acts { display:flex; gap:9px; margin-top:12px; }
.novoping-acts .btn { flex:1; margin:0; text-align:center; }
.novoping-acts .btn[hidden] { display:none; }
/* busy (#44): while THIS piece's image is generating, the ✦ becomes the status —
   a spinning ring replaces the sparkle; disabled until the job lands. */
/* Generating (s72, his call): the ✦ just greys OUT — muted disc, apagado glyph, no shadow, so it
   plainly recedes as "working, unavailable"; distinct from the amber .gated lock. No spinner, no
   pill: the shared "Gerando imagem…" bar carries the status here like on every other screen. */
.heropolish.busy { pointer-events:none; background:var(--paper-2); color:var(--ink-faint); border-color:var(--line); }
.heropolish.busy .heropolish-spark { fill:var(--ink-faint); }
/* Reframe IN PLACE (s16 → s77): the looks-page corner ⤢ toggle. Tap enters adjust (drag/pinch);
   share/rede tuck away, the ⤢ flips to a ✓, and a revert glyph appears beside it. */
.hero.reframing { cursor:grab; touch-action:none; }
.hero.reframing img { cursor:grab; }
.hero.reframing .heroshare { display:none; }
/* the corner controls, ported from the looks hero (.reframebtn / .reframe-toggle base live globally) */
.hero .reframectrls { position:absolute; right:12px; bottom:12px; z-index:4; display:flex; gap:8px; }
.hero .reframebtn svg { width:20px; height:20px; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.hero .reframe-toggle svg { stroke:#1a1a1a; }
.hero .reframe-revert svg { stroke:#fff; }
.hero.reframing .reframe-toggle { background:rgba(40,28,48,.62); box-shadow:none; }
.hero.reframing .reframe-toggle svg { stroke:#fff !important; }
.hero.reframing .reframe-toggle .rf-move { display:none; }
.hero.reframing .reframe-toggle .rf-check { display:block; stroke-width:2.4; }
.hero.reframing .reframe-revert { display:flex; }
.lightbox { position:fixed; inset:0; z-index:200; background:var(--paper); display:flex; align-items:center; justify-content:center; }
.lightbox[hidden] { display:none; }
.lb-img { max-width:100%; max-height:100%; object-fit:contain; transition:transform .2s ease; cursor:zoom-in; }
.board .img img { cursor:zoom-in; }
/* Aperfeiçoar: the render lightbox is a column — image in its own space (never
   hidden by chrome), the correction bar flows below it and grows with the text. */
/* The viewer follows the app theme (his call, s67): cream --paper in light, near-black
   in dark — it reads like every other screen instead of a forced-dark island (the old
   dark backdrop clashed with the light-theme keyboard/input, leaving a cream band). The
   render sits on paper like the acervo grid; the chrome below rides ink tokens. */
#mesaLightbox { flex-direction:column; justify-content:flex-start; background:var(--paper);
  padding-top:calc(env(safe-area-inset-top,0px) + 52px); }
/* The reframe frame (s26): the render crops into the board card's own 2:3 aspect, so
   what you frame here is WYSIWYG for the card. Rounded + clipped (like every stable
   pinch instrument), inset to line up with the Refazer button/field beneath it. */
.lb-frame { position:relative; flex:0 1 auto; align-self:center; aspect-ratio:2/3; max-width:calc(100% - 28px - env(safe-area-inset-left,0px) - env(safe-area-inset-right,0px));
  max-height:100%; min-height:0; overflow:hidden; border-radius:12px; touch-action:none;
  background:var(--paper-2); display:flex; }
#mesaLightbox .lb-img { width:100%; height:100%; object-fit:cover; touch-action:none; transition:none; cursor:zoom-in; }
#mesaLightbox .lb-frame.adjusting .lb-img { cursor:grab; }
/* The image scales within the frame and cannot reach the chrome, but keep the chrome
   explicitly above so no mid-gesture compositing promotion on iOS can reorder it. */
#mesaLightbox .lb-perfect { position:relative; z-index:2; }
/* Canon back-arrow, top-left — mirrors .topbar .back. */
#mesaLightbox .lb-back { position:absolute; top:calc(env(safe-area-inset-top,0px) + 14px);
  left:calc(14px + env(safe-area-inset-left,0px)); z-index:3; display:inline-flex; align-items:center;
  gap:6px; font-family:var(--sans); font-size:13px; color:var(--ink); text-decoration:none; }
#mesaLightbox .lb-back svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.5; fill:none; }
/* Overlay ON the frame (like the acervo hero's hint/bar), so showing them enters
   adjust WITHOUT nudging the image a pixel. */
.lb-hint { position:absolute; left:8px; right:8px; top:8px; z-index:4; text-align:center;
  font-family:var(--sans); font-size:12px; color:#fff; padding:6px 10px; border-radius:var(--r-ctl);
  background:rgba(0,0,0,.42); }
.lb-hint[hidden] { display:none; }
/* The reframe pair sits BELOW the frame in flow (not over the image) — a compact row
   above the Refazer bar, shown only in adjust. */
/* align-self:stretch: the column inherits align-items:center from .lightbox, which
   shrank this row to content width (smaller buttons) once it left the absolute overlay.
   Stretch it so the pair spans full width — same size as before, just below the image. */
.lb-reframe { flex:0 0 auto; align-self:stretch; box-sizing:border-box; display:flex; gap:10px; padding:10px 14px 2px; }
.lb-reframe[hidden] { display:none; }
.lb-reframe button { flex:1; padding:11px; border-radius:10px; font-family:var(--sans);
  font-size:14px; font-weight:600; cursor:pointer; border:1px solid var(--line-2);
  background:none; color:var(--ink); }
.lb-reframe .lb-reframe-ok { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.lb-reframe button:active { transform:scale(.98); }
.lb-perfect { flex:0 0 auto; width:100%; box-sizing:border-box;
  padding:12px calc(14px + env(safe-area-inset-left,0px)) calc(16px + env(safe-area-inset-bottom,0px)) calc(14px + env(safe-area-inset-right,0px)); }
.lb-perfect[hidden] { display:none; }
/* "O que saiu errado?" — the targeted-redo chips (s26). One selected; 'tudo' default. */
/* s73 (his call): the glyph alone, in a disc — the word went. 34px disc, 16px glyph (even
   difference, the glyph-in-a-disc rule); the label lives in aria-label. */
.lb-adjust-cue { position:absolute; bottom:10px; right:10px; width:34px; height:34px; display:grid;
  place-items:center; padding:0; border:none; border-radius:50%; background:rgba(15,12,9,.62); color:#fff;
  cursor:pointer; -webkit-appearance:none; appearance:none; -webkit-backdrop-filter:blur(3px);
  backdrop-filter:blur(3px); -webkit-tap-highlight-color:transparent; }
.lb-adjust-cue svg { width:16px; height:16px; display:block; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.lb-adjust-cue[hidden] { display:none; }
.lb-chips { margin-bottom:10px; }
.lb-chips[hidden] { display:none; }
.lb-chips-q { display:block; font-family:var(--sans); font-size:12px; color:var(--ink-soft); margin-bottom:6px; }
.lb-chips-row { display:flex; flex-wrap:wrap; gap:6px; }
.lb-chip { border:1px solid var(--line-2); background:none; color:var(--ink);
  font-family:var(--sans); font-size:13px; padding:7px 12px; border-radius:999px; cursor:pointer; }
.lb-chip.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
/* s73 (option A): four or more pieces → the ficha's value box (one 40px row, the choice +
   a chevron) opening the app's option sheet over the viewer — the frame never pays for
   a long look. Under four, the one-tap chips stay. */
.lb-door { display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%;
  box-sizing:border-box; min-height:40px; padding:9px 12px; border:0; border-radius:10px;
  background:var(--field); color:var(--ink); font-family:var(--sans); font-size:15px; text-align:left;
  cursor:pointer; -webkit-tap-highlight-color:transparent; }
.lb-door-v { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lb-door-chev { color:var(--ink-faint); font-size:18px; line-height:1; flex:none; }
.optsheet.lb-optsheet { z-index:210; }   /* above the lightbox (200) */
.lb-optsheet .optrow { white-space:normal; }
/* the teaching + the honest ceiling, at the point of need */
.lb-help { margin:10px 2px 0; font-family:var(--sans); font-size:12px; line-height:1.45;
  color:var(--ink-faint); }
.lb-perfect .lineup-generate { margin-top:10px; }
.lb-perfect textarea { resize:none; }
/* Transcribing (s72, rule D): an EMPTY field shows the in-field overlay, so the mic sits quiet
   (muted by .fieldmic busy opacity below). Dictating MORE into text (.mic-appending) skips the
   overlay — it would cover her words — so the mic PULSES as the beat instead. */
.fieldmic[data-state="busy"].mic-appending { animation:micbusy 1s ease-in-out infinite; }
@keyframes micbusy { 0%,100%{ opacity:1; } 50%{ opacity:.3; } }
/* In-box "AI is writing" beat: overlays the field where the text will land while the
   transcript is on its way. Sits at the field's text origin; .has-text drops it to the
   box's edge with a chip bg so it never covers what you already typed (mic appends). */
.fieldwait { position:absolute; left:13px; top:13px; display:flex; align-items:center; gap:2px;
  font-family:var(--sans); font-size:16px; color:var(--ink-faint); pointer-events:none; z-index:2; }
.fieldwait.has-text { top:auto; left:10px; bottom:8px; padding:3px 9px; font-size:13px;
  background:var(--paper); border-radius:999px; box-shadow:0 1px 4px rgba(20,16,10,.14); }
/* s75 (his call): in the Descrever box the overlay host (#descWrap) wraps the textarea with its
   own 10px padding, so the base left/top:13px (tuned for a textarea-as-host) lands the beat in
   the gap, left of the text. Shift it to the textarea's text origin and match the 13px placeholder. */
#descWrap .fieldwait { left:23px; top:23px; font-size:13px; }
.lb-img.zoom { transform:scale(2.2); cursor:zoom-out; }
.lb-close { position:absolute; top:calc(env(safe-area-inset-top,0px) + 12px); right:16px; width:40px; height:40px; border-radius:50%; background:rgba(255,255,255,.16); color:#fff; border:none; font-size:26px; line-height:1; cursor:pointer; display:grid; place-items:center; }
.thumbs { display:flex; flex-wrap:wrap; gap:9px; margin:10px 0 36px; }   /* s50 (his call, option A): the visual block breathes before the text — the acervo's section rhythm */
/* FIVE PER ROW, spanning the hero exactly (s50, his call): the tile is a fifth of the
   column minus the four 9px gaps — 59px on a 375pt phone, 70px on a 430pt one — so the
   row always ends where the hero ends, and the marks the tile carries (star / number
   top-right, IA · ETIQUETA · REF bottom-left) keep their room on every phone. */
.thumb { width:calc((100% - 36px) / 5); aspect-ratio:2/3; border-radius:5px; border:1px solid var(--line); display:grid; place-items:center; overflow:hidden; }
.editable .ed { -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
.ed.editing { display:block; }
.meta .ed.editing, .sub.ed.editing { display:inline-block; }
/* an empty field reads as a quiet "add" affordance — long-press to fill it in */
.vsep { color:var(--ink-faint); margin:0 6px; }
.vqual { color:var(--ink-soft); font-size:.92em; }   /* size system = quiet qualifier */
.ed.emptyfield { color:var(--accent); font-weight:500; opacity:.75; }
h1.ed.emptyfield, .sub.ed.emptyfield { font-weight:600; }
.notes.ed.emptyfield { font-size:16px; }  /* match the Etiquetas "+ adicionar" size */
/* warnfield (#32): categoria 'Outro'/blank + época blank — the fields a failed AI
   read leaves wrong. A quiet red state that can't be scrolled past unnoticed. */
.ed.warnfield { display:inline-block; color:var(--danger); opacity:1; font-weight:600;
  background:color-mix(in srgb, var(--danger) 7%, transparent);
  border:1px dashed color-mix(in srgb, var(--danger) 40%, transparent);
  border-radius:7px; padding:2px 9px; }
.sub.ed.warnfield { margin-top:6px; }
/* Mais detalhes — secondary ficha fields, tucked behind a collapse */
.moredetails { margin:14px 0 0; }
.moredetails > summary { font-size:13px; font-weight:500; letter-spacing:.01em; color:var(--accent);
  cursor:pointer; list-style:none; padding:6px 2px; }
.moredetails > summary::-webkit-details-marker { display:none; }
.moredetails > summary::after { content:" ▸"; color:var(--ink-faint); }
.moredetails[open] > summary::after { content:" ▾"; }
.moredetails .meta { margin-top:4px; }
/* Pinned to the top of the scrolling list: the sheet centres the SELECTED value on
   open, so a value low in a long vocab (Dourado is 13th of 16 colours) pushed
   "— remover —" above the fold — measured at y=-40, invisible at the moment it's
   wanted. Sticky keeps both affordances. Opaque + a hairline, or rows scroll through
   it; square corners because the border is single-sided. */
.slabel.tagslabel { margin-bottom:9px; }
/* Try-on panel — a collapsible section so the "on a person" renders aren't a
   floating grid; summary reads at section-header weight (matches .piece-detail .slabel) */
.tryonpanel { margin:0; }
.tryonpanel > summary { font-family:var(--serif); font-size:17px; font-weight:500; color:var(--ink);
  cursor:pointer; list-style:none; padding:2px 0; display:flex; align-items:center; gap:6px; }
.tryonpanel > summary::-webkit-details-marker { display:none; }
.tryonpanel > summary::after { content:"▸"; font-size:12px; color:var(--ink-faint); margin-left:2px; }
.tryonpanel[open] > summary::after { content:"▾"; }
.tryonpanel-body { margin-top:12px; }
.txtsheet[hidden] { display:none; }
/* s80: centre the sheet vertically (was top-pinned with a 0 bottom pad, so the buttons kissed
   the screen edge). margin:auto on the panel centres it when it fits and pins-to-top-and-scrolls
   when it's taller than the viewport (no clipped top, unlike align-items:center); the container
   pads with the home-indicator safe area so nothing ever touches the bottom. */
.txtsheet { position:fixed; inset:0; z-index:96; display:flex; align-items:flex-start; justify-content:center;
  overflow-y:auto; padding:4vh 16px calc(4vh + env(safe-area-inset-bottom)); }
.txtsheet-backdrop { position:fixed; inset:0; background:rgba(20,16,10,.5); }
.txtsheet-panel { position:relative; margin:auto; width:100%; max-width:520px; background:var(--paper); border-radius:14px; padding:16px;
  box-shadow:0 10px 40px rgba(0,0,0,.28); display:flex; flex-direction:column; gap:12px; }
.txtsheet-label { font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint); }
.txtsheet-input { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:16px; line-height:1.5; color:var(--ink);
  background:var(--paper); border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:10px 12px; outline:none; resize:none; min-height:52px; overflow:hidden; }
.txtsheet-input:focus { border-color:var(--accent); }
.txtsheet-actions { display:flex; gap:10px; }
.txtsheet-actions button { flex:1; font-family:var(--sans); font-size:14px; font-weight:500; border-radius:var(--r-ctl); padding:12px; cursor:pointer; }
.txtsheet-cancel { border:1px solid var(--line-2); background:var(--paper); color:var(--ink-soft); }
.txtsheet-go { border:1px solid var(--accent); background:var(--accent); color:var(--on-accent); }
.edmat { display:inline-flex; flex-wrap:wrap; gap:6px; align-items:center; }
.edmat-chip { font-family:var(--sans); font-size:12.5px; color:var(--ink-soft); border:1px solid var(--line-2); border-radius:2px; padding:5px 10px; background:var(--paper); cursor:pointer; }
.edmat-chip.on { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }
/* "+ mais" reveals the specific materials (s72) — a quiet ghost chip, clearly NOT a material:
   dashed, faint, no fill, so it reads as an action, not an option. */
.edmat-more { font-family:var(--sans); font-size:12.5px; color:var(--ink-faint); border:1px dashed var(--line-2); border-radius:2px; padding:5px 10px; background:none; cursor:pointer; }
.optsheet[hidden] { display:none; }
.optsheet { position:fixed; inset:0; z-index:95; display:flex; align-items:flex-end; }
.optsheet-backdrop { position:absolute; inset:0; background:rgba(20,16,10,.42); }
.optsheet-panel { position:relative; width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:16px 16px 0 0; padding:10px 12px calc(16px + env(safe-area-inset-bottom));
  box-shadow:0 -8px 30px rgba(0,0,0,.22); }
.optsheet-list { max-height:56vh; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.optsheet-empty { margin:6px 2px; font-size:13px; color:var(--ink-faint); }
.optsheet-scope { margin:2px 4px 8px; font-size:12px; letter-spacing:.02em; color:var(--ink-faint); text-transform:lowercase; }
/* s74 — the facet-scope switch (meu acervo | a rede) at the top of the Tipo sheet. */
.optscope { display:flex; background:var(--paper-2); border-radius:11px; padding:3px; margin:2px 2px 10px; }
.optscope-seg { flex:1; text-align:center; font-family:var(--sans); font-size:13.5px; font-weight:600;
  padding:9px 6px; border-radius:8px; text-decoration:none; color:var(--ink-faint); }
.optscope-seg.on { background:var(--card); color:var(--ink); box-shadow:0 1px 3px rgba(0,0,0,.12); }
.optscope-seg:active { color:var(--ink); }
/* .optrow dresses <button> AND <a> — same rule as .btn: strip the anchor's default
   underline or every linked option row renders as hyperlink-in-a-sheet. */
.optrow { display:flex; align-items:center; justify-content:space-between; width:100%; box-sizing:border-box;
  padding:14px 14px; border:none; background:none; font-family:var(--sans); font-size:16px; color:var(--ink);
  text-align:left; cursor:pointer; border-radius:10px; text-decoration:none; }
.optrow:active { background:var(--paper-2); }
.optrow[data-hold-delete] { position:relative; }
.optrow .hold-ring { position:absolute; right:10px; top:50%; width:24px; height:24px; margin-top:-12px; pointer-events:none; opacity:0; border-radius:50%; }
.optrow.holding .hold-ring { opacity:1; }
.optrow.on { color:var(--accent); font-weight:500; }
.optrow.on::after { content:"✓"; font-size:15px; }
/* COLOUR OVERRIDE = a swatch grid (s53b): the group is chosen by its actual colour, not a
   text row. Estampado/Multicor render a woven multi-hue dot (the 'not one colour' answer). */
.optswatches { display:grid; grid-template-columns:repeat(4,1fr); gap:14px 8px; padding:12px 6px 6px; }
.optsw { display:flex; flex-direction:column; align-items:center; gap:6px; border:0; background:none;
  cursor:pointer; font-family:var(--sans); -webkit-tap-highlight-color:transparent; padding:0; }
.optsw-dot { width:38px; height:38px; border-radius:50%; border:1px solid var(--hair); background:var(--line-2); }
.optsw.on .optsw-dot { box-shadow:0 0 0 2px var(--card), 0 0 0 4px var(--accent); }
.optsw--pattern .optsw-dot { background:conic-gradient(from 0deg,#A4271F,#E3B23C,#4E6B3A,#2F5A8C,#6E4A8E,#A4271F); }
.optsw-lbl { font-size:11px; line-height:1.1; color:var(--ink-soft); text-align:center; }
.optsw.on .optsw-lbl { color:var(--accent); font-weight:600; }
/* The merged what-is-it sheet (s36): category HEADINGS are themselves tappable
   (the coarse filter — and the only door for the no-Tipo categories), her tipos
   sit indented beneath. Selected heading = the plum fill idiom; selected tipo
   keeps the standard .optrow.on read. */
.optgroup { display:flex; align-items:center; justify-content:space-between; width:100%; box-sizing:border-box;
  margin-top:6px; padding:11px 14px 8px; border:none; border-bottom:1px solid var(--line);
  background:none; font-family:var(--sans); font-size:11.5px; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; color:var(--accent);
  text-align:left; cursor:pointer; border-radius:10px 10px 0 0; text-decoration:none; }
.optgroup:first-child { margin-top:0; }
.optgroup:active { background:var(--paper-2); }
.optgroup .optcount { letter-spacing:0; text-transform:none; }
.optgroup.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); border-radius:10px; }
.optgroup.on .optcount { color:var(--on-accent); }
.optgroup.on::after { content:"✓"; font-size:13px; margin-left:8px; }
.optrow.opttipo { padding-left:28px; }
.optsheet-suggest { width:100%; margin-top:8px; padding:13px 14px; border:none; border-top:1px solid var(--line);
  background:none; font-family:var(--sans); font-size:13.5px; color:var(--ink-soft); text-align:center;
  letter-spacing:.01em; cursor:pointer; }
.optsheet-suggest .sug-verb { color:var(--accent); }
.optsheet-suggest:active { background:var(--paper-2); }
.optsheet-foot { display:flex; gap:8px; margin-top:6px; }
/* Both footer buttons share ONE box (equal height, centred) so the glyph in the clear
   button can't make it taller than Cancelar. */
.optsheet-foot button { flex:1; display:flex; align-items:center; justify-content:center; gap:7px;
  min-height:50px; padding:0 14px; border:none; border-radius:12px; background:var(--paper-2);
  font-family:var(--sans); font-size:15px; font-weight:600; cursor:pointer; }
.optsheet-cancel { color:var(--ink-soft); }
/* The clear action, named ("Sem época") — plum text + a ⊘ glyph so it reads as an action,
   not a dismiss. Hidden for non-clearable fields (data-noclear). */
.optsheet-clear { color:var(--accent); }
.optsheet-clear svg { width:17px; height:17px; stroke:currentColor; stroke-width:1.8; fill:none; stroke-linecap:round; }
.optsheet-clear[hidden] { display:none; }
.optsheet-clear:active, .optsheet-cancel:active { filter:brightness(.96); }
.thumbadd { position:relative; border:none; background:none; color:var(--ink-faint); cursor:pointer; }
.thumbadd svg { width:20px; height:20px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.thumbadd input[type=file] { position:absolute; inset:0; width:100%; height:100%; margin:0; padding:0; border:0; opacity:0; cursor:pointer; -webkit-appearance:none; appearance:none; font-size:16px; }
.tt { margin-top:22px; }
.tt h1 { font-family:var(--serif); font-size:27px; font-weight:500; letter-spacing:.01em; line-height:1.12; }
.tt .sub { font-size:13px; color:var(--ink-faint); margin-top:7px; letter-spacing:.02em; }
.status { display:flex; align-items:center; gap:8px; font-size:13.5px; margin-top:13px; color:var(--ok); }
.status.muted { color:var(--ink-faint); }
.status.sold { color:var(--accent); font-weight:600; }
.status .dot { width:7px; height:7px; border-radius:50%; background:currentColor; }
hr.rule { border:none; border-top:1px solid var(--line); margin:24px 0; }
.meta { display:flex; flex-direction:column; }
.piece-detail .meta { margin-top:22px; }
.row { display:flex; align-items:center; justify-content:space-between; gap:14px; padding:12px 0; border-bottom:1px solid var(--line); }
.row:first-child { border-top:1px solid var(--line); }
.row .k { font-size:12px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); }
.row .v { font-size:15px; color:var(--ink); text-align:right; }
.row .v.tnum { font-variant-numeric:tabular-nums; }
/* medido badge — a piece with tape measurements is a grounded (not guessed) size */
.medido { margin-left:8px; font-size:10px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ok); background:color-mix(in srgb, var(--ok) 12%, transparent);
  border-radius:999px; padding:2px 7px; vertical-align:middle; }
/* Medidas row — display-only chips; a tap opens the popup for data entry */
.measrow { align-items:flex-start; }
.measrow .k .cm { display:block; text-transform:none; letter-spacing:0; font-size:10px; color:var(--ink-faint); margin-top:2px; }
.row .v.measures { display:flex; flex-wrap:wrap; gap:6px 12px; justify-content:flex-end; align-items:baseline;
  border:none; background:none; font:inherit; cursor:pointer; padding:0; text-align:right; }
.measure { display:inline-flex; align-items:baseline; gap:5px; }
.measure .ml { font-size:11px; color:var(--ink-faint); }
.measure .mv { font-variant-numeric:tabular-nums; color:var(--ink); }
.measedit { font-size:11px; color:var(--accent); align-self:center; }
/* empty-state trigger (opens the popup) — accent '+ adicionar' look, but NOT an .ed
   inline field, so it can't double-open the generic text editor */
.measempty { border:none; background:none; font:inherit; color:var(--accent); font-weight:500;
  opacity:.75; cursor:pointer; padding:0; text-align:right; }
/* Measurements popup — one comfortable form for all the garment's fields */
.measuresheet .txtsheet-label small { text-transform:none; letter-spacing:0; font-size:11px; color:var(--ink-faint); margin-left:5px; }
.measurefld { display:flex; align-items:center; justify-content:space-between; gap:14px; padding:9px 0; border-bottom:1px solid var(--line); }
.measurefld-l { font-size:15px; color:var(--ink); }
/* structured cm box — mirrors .phonewrap: a bordered input glued to a fixed unit
   segment, so tape entry looks/behaves like the WhatsApp field (unit trailing). */
.measurewrap { display:flex; align-items:stretch; gap:6px; flex:none; }
.measurewrap input { width:4.5ch; text-align:right; font-variant-numeric:tabular-nums;
  border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper); color:var(--ink);
  font-family:var(--sans); font-size:16px; padding:9px 10px; outline:none;
  -webkit-appearance:none; appearance:none; }
.measurewrap input:focus { border-color:var(--accent); }
.measurewrap .cmunit { flex:none; display:flex; align-items:center; justify-content:center; padding:0 11px;
  border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper-2); color:var(--ink-soft); font-size:13px; }
.measurewrap:focus-within .cmunit { border-color:var(--accent); }
/* structured size popup — native selects, sized to their content */
.sizesel { min-width:9ch; border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper);
  color:var(--ink); font-family:var(--sans); font-size:16px; padding:9px 30px 9px 12px; outline:none;
  -webkit-appearance:none; appearance:none; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235E6963' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 9px center; background-size:16px; }
.sizesel:focus { border-color:var(--accent); }
/* band picker — the primary size input (a bare P/M/G is usually all a tag gives) */
.sizeband { display:flex; gap:8px; flex-wrap:wrap; margin:2px 0 4px; }
.bandchip { flex:1 1 0; min-width:52px; border:1px solid var(--line-2); border-radius:12px;
  background:var(--paper); color:var(--ink); font-family:var(--sans); font-size:17px; font-weight:600;
  padding:14px 8px; cursor:pointer; -webkit-appearance:none; appearance:none; }
.bandchip.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.bandchip-none { flex:1 1 100%; font-size:14px; font-weight:500; }
.sizeexact { margin-top:12px; border-top:0.5px solid var(--line); padding-top:8px; }
.sizeexact > summary { font-size:13px; color:var(--ink-soft); cursor:pointer; padding:6px 2px; list-style:none; }
.sizeexact > summary::-webkit-details-marker { display:none; }
.sizeexact > summary::before { content:"+ "; color:var(--accent); }
.sizeexact[open] > summary::before { content:"− "; }
.brconv[hidden] { display:none; }
.brconv { text-align:right; font-size:13px; color:var(--accent); font-variant-numeric:tabular-nums; margin:2px 2px 0; }
.notes { font-size:14px; color:var(--ink-soft); line-height:1.55; }
.notes.deitadas { color:var(--warn); margin:6px 0 10px; }   /* s70: a refused sideways shot, said once */
.provarheads { font-size:12.5px; line-height:1.5; color:var(--warn); background:var(--warn-tint);
  border-radius:10px; padding:9px 12px; margin:0 0 12px; }
.provarheads b { font-weight:600; }
.welcomebar { display:flex; align-items:center; gap:9px; font-size:12.5px; color:var(--accent);
  background:var(--tint); border-radius:12px; padding:10px 14px; margin:4px 2px 12px; line-height:1.4; }
.welcomebar b { font-weight:700; }
.welcomebar .wb-g { width:13px; height:13px; fill:var(--dot); flex:none; }
/* The arrival vouch door (s64): on an empty invited acervo — who brought her in + a way back to the rede. */
.voucharrive { display:flex; align-items:center; gap:11px; margin:16px 2px 4px; padding:12px 13px;
  border-radius:13px; border:1px solid var(--line-2); background:var(--card); text-decoration:none; color:inherit; }
.voucharrive .va-face { flex:none; width:38px; height:38px; border-radius:50%; background:var(--accent);
  color:var(--on-accent); display:grid; place-items:center; font-weight:700; font-size:15px; }
.voucharrive .va-txt b { display:block; font-size:13.5px; color:var(--ink); }
.voucharrive .va-txt small { display:block; font-size:11.5px; color:var(--ink-soft); margin-top:1px; }
.voucharrive .va-arr { margin-left:auto; flex:none; width:20px; height:20px; stroke:var(--ink-faint);
  stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.voucharrive:active { background:var(--paper-2); }
/* the rede band's tiles on the acervo search (the rede tab's own results grid retired s84) */
.redetile { display:flex; flex-direction:column; text-decoration:none; color:inherit; }
/* Maker ("quem faz") result card + the Perfil crafts picker (s54 step 4) */
.mkcard { display:flex; gap:11px; align-items:center; background:var(--card); border:1px solid var(--line);
  border-radius:14px; padding:11px 12px; margin-bottom:8px; }
.mkav { width:46px; height:46px; border-radius:50%; background:var(--paper-2); flex:none; overflow:hidden;
  display:flex; align-items:center; justify-content:center; font-family:var(--serif); font-size:17px; color:var(--ink-soft); }
.mkav img { width:100%; height:100%; object-fit:cover; }
.mkmeta { flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.mkmeta b { font-size:14px; font-weight:600; letter-spacing:-.01em; }
.mkcrafts { display:flex; gap:5px; flex-wrap:wrap; }
.mkcraft { display:inline-flex; align-items:center; font-size:11px; color:var(--accent); background:var(--tint); border-radius:6px; padding:3px 7px; }
.mkloc { font-size:11.5px; color:var(--ink-soft); display:flex; align-items:center; gap:4px; }
.mkloc svg { width:12px; height:12px; stroke:var(--accent); stroke-width:1.8; fill:none; }
.mkzap { width:36px; height:36px; border-radius:50%; background:var(--ok); flex:none; text-decoration:none;
  display:flex; align-items:center; justify-content:center; }
.mkzap svg { width:18px; height:18px; fill:#fff; }
/* s58 — the ✂ glyph taught at its source: it rides the "O que você faz" label so the
   user learns it here (the one place they choose what it means) and recognises it on cards. */
.lbl-scis { width:15px; height:15px; fill:none; stroke:var(--dot); stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round; vertical-align:-3px; margin-left:3px; }
.craftpick { display:flex; flex-wrap:wrap; gap:8px; margin:4px 0 2px; }
.craftpick .craftopt { font-size:13px; color:var(--ink-soft); background:var(--paper-2); border:1px solid var(--line);
  border-radius:20px; padding:6px 13px; cursor:pointer; user-select:none; }
.craftpick .craftopt input { position:absolute; opacity:0; pointer-events:none; }
.craftpick .craftopt:has(input:checked) { background:var(--accent); color:var(--on-accent); border-color:var(--accent); }
.tags { display:flex; gap:8px; flex-wrap:wrap; margin-top:18px; }
.tag { font-size:12px; color:var(--ink-soft); border:1px solid var(--line-2); border-radius:999px; padding:5px 12px; }

/* form */
.form { display:flex; flex-direction:column; gap:16px; }
.form .f { display:flex; flex-direction:column; gap:6px; }
.form .f2 { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.lbl { font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint); }
/* s78 (his call): per-field 'salvo' — flashes green on the field's own label line (top-right of
   its .f), so the receipt lands where you just typed, not in the form's top corner. */
.pfform .f { position:relative; }
.lbl-saved { position:absolute; top:0; right:0; font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ok); opacity:0; transition:opacity .22s; pointer-events:none; }
.lbl-saved.on { opacity:1; }
.form input, .form select, .form textarea { width:100%; font-family:var(--sans); font-size:15px; color:var(--ink); background:var(--field); border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:11px 12px; outline:none; -webkit-appearance:none; appearance:none; }
.form input:focus, .form select:focus, .form textarea:focus { border-color:var(--accent); }
.form input.err, .form textarea.err { border-color:var(--brick); background:var(--err-bg); }
/* field hints — quiet, small, secondary (never louder than the field itself) */
.form .hint { display:block; font-size:11.5px; color:var(--ink-faint); margin-top:5px; line-height:1.4; }
/* error-only hints (s25 S/N pass): an empty slot takes no space until a validation
   message fills it */
.form .hint:empty { display:none; }
/* Fiscal address (s33): street → complemento → CEP, each on its own line (.form .f is
   a flex column). CEP stays narrow; the street is an auto-growing textarea (acrvoGrow) so
   comically long BR street names wrap to a second line instead of clipping. */
.f .cepfld { width:132px; }
.form input.halffld { width:55%; margin-top:8px; }

/* IM opt-in: a quiet checkbox row; the field unfolds under it when ticked */
.imtoggle { display:flex; align-items:center; gap:9px; cursor:pointer; font-size:13.5px; color:var(--ink-soft); }
/* A CHECKBOX YOU CAN READ (s49, his phone: 'no way to know if it's on or off'): .form input
   dresses every input with a field background + border, and iOS then draws a checkbox as a
   bare bordered square with NO tick. So the box is drawn by hand — the same on every
   browser: an outlined square at rest, plum with a white tick when on. */
.form .imtoggle input[type=checkbox], .onboard-termscheck input[type=checkbox], input.acrvo-check {
  -webkit-appearance:none; appearance:none; width:22px; height:22px; flex:none; margin:0; padding:0;
  border:1.5px solid var(--line-2); border-radius:6px; background:var(--field); position:relative;
  cursor:pointer; box-shadow:none; }
.form .imtoggle input[type=checkbox]:checked, .onboard-termscheck input[type=checkbox]:checked, input.acrvo-check:checked {
  background:var(--accent); border-color:var(--accent); }
.form .imtoggle input[type=checkbox]:checked::after, .onboard-termscheck input[type=checkbox]:checked::after, input.acrvo-check:checked::after {
  content:""; position:absolute; left:7px; top:3px; width:5px; height:10px; border:solid var(--on-accent);
  border-width:0 2.2px 2.2px 0; transform:rotate(45deg); }
.imtoggle .inline-saved { position:static; margin-left:auto; }
.imfield { display:flex; flex-direction:column; gap:6px; margin-top:12px; }
.imfield[hidden] { display:none; }

/* the acréscimos pair (Preços e regras): two halves, micro-legend under each */
.pctrow { display:flex; gap:10px; margin-top:6px; }
.pcthalf { flex:1; min-width:0; display:flex; flex-direction:column; gap:4px; }
.pcthalf .hint, .catprices .hint { display:block; font-size:11.5px; color:var(--ink-faint); line-height:1.4; }
.catprices .hint:empty { display:none; }
.catprices .lbl { font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint); }
.catprices form[data-autosave] { position:relative; margin-bottom:16px; }
.form .hint.err { color:var(--brick); }
/* WhatsApp: a fixed +55 adornment — its own self-contained rounded box, so the
   number field beside it holds only the DDD+number */
/* Money gate — mirrors .phonewrap: a fixed R$ prefix glued to a live-formatted amount. */
.moneywrap { display:flex; align-items:stretch; gap:8px; }
.moneywrap .rsym { flex:none; display:flex; align-items:center; justify-content:center; padding:0 15px;
  border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper-2); color:var(--ink-soft);
  font-size:15px; font-weight:600; line-height:1; }
.moneywrap:focus-within .rsym { border-color:var(--accent); color:var(--accent); }
.moneywrap input { flex:1; min-width:0; width:100%; box-sizing:border-box; font-family:var(--sans);
  font-size:15px; color:var(--ink); background:var(--paper); border:1px solid var(--line-2);
  border-radius:var(--r-ctl); padding:12px 14px; outline:none; font-variant-numeric:tabular-nums; }
.moneywrap input:focus { border-color:var(--accent); }
.inline-field .moneywrap input { font-size:16px; }
.phonewrap { display:flex; align-items:stretch; gap:8px; }
.phonewrap .ccode { flex:none; display:flex; align-items:center; justify-content:center; padding:0 16px 0 12px;
  border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper-2); color:var(--ink-soft);
  font-size:15px; line-height:1; font-variant-numeric:tabular-nums; }
.phonewrap:focus-within .ccode { border-color:var(--accent); }
.phonewrap.err .ccode { border-color:var(--brick); background:var(--err-bg); }
/* self-contained input box so the phonewrap looks identical outside .form
   (e.g. the orçamento header's inline-edit form) — matches .form input exactly */
.phonewrap input { flex:1; min-width:0; width:100%; font-family:var(--sans); font-size:15px;
  color:var(--ink); background:var(--field); border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:11px 12px; line-height:1.35; outline:none; -webkit-appearance:none; appearance:none; }
.phonewrap input:focus { border-color:var(--accent); background:var(--field); }
/* beat the borderless .inline-field input when the phonewrap sits in the orçamento header */
.inline-field .phonewrap input { border:1px solid var(--line-2); background:var(--field);
  border-radius:var(--r-ctl); padding:11px 12px; font-size:15px; }
.inline-field .phonewrap input:focus { border-color:var(--accent); }
/* auto-save "salvo" flash — the Perfil form saves on blur, no button */
.autosaved { display:block; align-self:flex-end; margin-bottom:-4px; font-size:10px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ok); opacity:0; transition:opacity .22s; height:13px; pointer-events:none; }
.autosaved.on { opacity:1; }
.form textarea { resize:vertical; }
.form select { background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236F6657' stroke-width='1.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 10px center; background-size:18px; padding-right:34px; }
.chips { display:flex; flex-wrap:wrap; gap:8px; }
.chip { position:relative; }
.chip input { position:absolute; opacity:0; width:0; height:0; }
.chip span { display:inline-block; font-size:12.5px; color:var(--ink-soft); border:1px solid var(--line-2); border-radius:2px; padding:7px 13px; cursor:pointer; transition:all .15s; }
.chip input:checked + span { background:var(--accent); color:var(--on-accent); border-color:var(--accent); }
.form .morefields { border-top:1px solid var(--line); padding-top:4px; }
.form .morefields summary { list-style:none; cursor:pointer; font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-soft); display:inline-flex; align-items:center; gap:7px; padding:8px 2px; }
.form .morefields summary::-webkit-details-marker { display:none; }
.form .morefields summary::before { content:"⏷"; font-size:10px; color:var(--ink-faint); transition:transform .15s; }
.form .morefields[open] summary::before { transform:rotate(180deg); }
.form .morefields-body { display:flex; flex-direction:column; gap:16px; margin-top:10px; }
.photo-input { display:block; cursor:pointer; }
.photo-empty { aspect-ratio:16/10; border:1px dashed var(--line-2); border-radius:10px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; color:var(--ink-faint); background:var(--paper-2); }
.photo-empty svg { width:30px; height:30px; stroke:currentColor; stroke-width:1.3; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.photo-empty span { font-size:13px; }
.photo-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.photo-grid img { aspect-ratio:2/3; border-radius:var(--r-card); border:1px solid var(--line); }
.save { margin-top:8px; width:100%; background:var(--accent); color:var(--on-accent); border:none; border-radius:var(--r-ctl); padding:15px; font-family:var(--sans); font-size:15px; font-weight:500; letter-spacing:.02em; cursor:pointer; }
.save:active { background:var(--accent-press); }

/* ---- M2b: capture (snap-and-talk) ---- */
.capnote { font-size:13px; color:var(--ink-faint); line-height:1.5; text-align:center; margin-top:14px; }
.gcerr { font-size:13px; color:var(--red); line-height:1.5; text-align:center; margin-top:12px; }
.capshot { aspect-ratio:2/3; max-height:42vh; border-radius:10px; overflow:hidden; border:1px solid var(--line); background:var(--paper-2); margin:0 auto; }
.capshot img { width:100%; height:100%; object-fit:cover; display:block; }
.describe { display:flex; flex-direction:column; align-items:center; text-align:center; gap:10px; padding-top:12px; }
.micbig { width:78px; height:78px; border-radius:50%; background:var(--accent); border:none; display:grid; place-items:center; cursor:pointer; margin-top:6px; transition:transform .15s; }
.micbig:active { transform:scale(.95); }
.micbig.on { animation:micpulse 1.4s ease-out infinite; }
.micbig svg { width:32px; height:32px; stroke:var(--on-accent); stroke-width:1.5; fill:none; stroke-linecap:round; stroke-linejoin:round; }
@keyframes micpulse { 0% { box-shadow:0 0 0 0 rgba(20,20,20,.4); } 100% { box-shadow:0 0 0 18px rgba(20,20,20,0); } }
.caplead { font-family:var(--serif); font-size:18px; font-weight:500; }
.caphelp { font-size:12.5px; color:var(--ink-faint); max-width:240px; line-height:1.5; }
.describe textarea { width:100%; margin-top:6px; font-family:var(--sans); font-size:15px; color:var(--ink); background:var(--field); border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:11px 12px; outline:none; resize:vertical; }
.describe textarea:focus { border-color:var(--accent); }
.describe .save, .describe .redo { width:100%; }
.capmsg { font-size:13px; color:var(--warn); }
.saidrow { display:flex; gap:9px; align-items:flex-start; background:var(--paper-2); border-radius:var(--r-ctl); padding:12px 14px; margin-bottom:18px; }
.saidrow .q { flex:none; color:var(--accent); font-family:var(--serif); font-size:18px; line-height:1; }
.saidrow .said { font-size:13px; color:var(--ink-soft); font-style:italic; line-height:1.5; }
.heard { font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint); display:flex; align-items:center; gap:7px; margin:6px 0 14px; }
.heard svg { width:13px; height:13px; stroke:var(--accent); stroke-width:1.3; fill:none; }
.redo { display:block; margin:12px auto 0; font-size:12.5px; color:var(--ink-faint); background:none; border:none; cursor:pointer; width:100%; }

.actions { margin-top:18px; }
/* .btn dresses BOTH <button> and <a> — the anchor keeps the browser's link underline
   unless stripped (a real button never had one), so without this a .btn link renders
   as a hybrid: button shell, hyperlink typography. 12 anchors app-wide wear this. */
.btn { width:100%; display:inline-block; box-sizing:border-box; text-align:center; text-decoration:none; background:var(--paper); color:var(--ink); border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:14px; font-family:var(--sans); font-size:14.5px; font-weight:500; letter-spacing:.02em; cursor:pointer; }
/* s83: .btn's display beat the UA [hidden] rule, so a hidden .btn still showed (the invite sheet's
   two 'Enviar convite', the capture recarga door, the borrower share button). Scoped to .btn — a
   global [hidden] reset would break the sheets that stay in the tree on purpose (.rcsheet, .fbsheet). */
.btn[hidden] { display:none; }
.btn:active { border-color:var(--ink); }
/* "Você quis dizer …?" (s62): the typo offer leads the dead-end acts — accent border so it
   reads as the suggested next step, its <b> word the accent. */
.btn.dym { border-color:var(--accent); }
.btn.dym b { color:var(--accent); font-weight:600; }
.btn.danger { color:var(--accent); border-color:var(--line-2); }
.btn.danger:active { border-color:var(--accent); background:var(--paper-2); }
.trash-banner { font-size:13px; color:var(--ink-soft); background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-ctl); padding:12px 14px; margin-bottom:14px; }
/* a lixeira. — esvaziar rides the title row (s27); .btn is width:100% by default */
.trashtitle { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.trashtitle h1 { min-width:0; }
.trashtitle .btn { width:auto; flex:none; padding:11px 16px; font-size:13.5px; }
.archive-foot { display:flex; justify-content:center; padding:34px 0 18px; }
.ghostlink { font-size:12.5px; letter-spacing:.04em; color:var(--ink-faint); text-decoration:none; }
.ghostlink:active { color:var(--ink); }

.search { margin:14px 0 4px; }
.searchbar { display:flex; align-items:center; gap:9px; border:1px solid var(--line-2); border-radius:999px; padding:9px 9px 9px 15px; background:var(--paper); }
.searchbar svg { width:17px; height:17px; stroke:var(--ink-faint); stroke-width:1.7; fill:none; stroke-linecap:round; flex:none; }
.searchbar input { flex:1; border:none; background:none; font-family:var(--sans); font-size:15px; color:var(--ink); outline:none; min-width:0; }
.searchbar input::placeholder { color:var(--ink-faint); }
.searchbar button { flex:none; border:none; background:var(--accent); color:var(--on-accent); border-radius:999px; padding:8px 16px; font-family:var(--sans); font-size:13px; font-weight:500; cursor:pointer; }
.searchbar button:active { background:var(--accent-press); }
.filters { margin-top:10px; }
/* Lote uniforme (s35, the folder insight): the batch declaration card on /importar —
   a lifted card so the two fields read as one deliberate act, not loose inputs. */
.lotecard { margin:2px 0 14px; }
.lotecard[open] { background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
  padding:4px 13px 13px; box-shadow:0 4px 14px var(--shadow); }
.lotecard[open] > summary { padding:9px 0 6px; }
.lotefields { gap:12px; margin-top:4px; }
.filters summary { list-style:none; cursor:pointer; font-size:12.5px; letter-spacing:.04em; color:var(--ink-soft); padding:6px 2px; display:inline-flex; align-items:center; gap:6px; }
.filters summary::-webkit-details-marker { display:none; }
.filters summary::before { content:"⏷"; font-size:10px; color:var(--ink-faint); transition:transform .15s; }
.filters[open] summary::before { transform:rotate(180deg); }
.facet { margin:12px 0; }
.facet-label { font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-faint); margin-bottom:8px; }
.filters .chips { display:flex; flex-wrap:wrap; gap:7px; }
.filters .chip { position:relative; font-size:12.5px; color:var(--ink-soft); border:1px solid var(--line-2); border-radius:2px; padding:6px 12px; cursor:pointer; user-select:none; }
.filters .chip input { position:absolute; opacity:0; pointer-events:none; }
.filters .chip.on, .filters .chip:has(input:checked) { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }
.filter-actions { display:flex; align-items:center; gap:16px; margin-top:14px; }
.apply { background:var(--ink); color:var(--paper); border:none; border-radius:var(--r-ctl); padding:11px 18px; font-family:var(--sans); font-size:13px; font-weight:500; cursor:pointer; }
.resultline { display:flex; align-items:center; gap:14px; font-size:12.5px; color:var(--ink-faint); margin:16px 2px 4px; }
/* Private-exception badge on grid tiles — marks ONLY a piece held OUT of a shared
   category (the card's "N fora", piece by piece). Uniformly-private categories stay
   silent: the state is category-level and lives on the card's dim globe. */
.tile .img { position:relative; }
/* Rede state, lower-left glyph disc (s80): ✦ falta polir (action) · cadeado você tirou
   (state). One slot, mutually exclusive; on-the-rede pieces wear nothing. */
/* Scoped under .tile .img to beat the generic `.tile .img svg` placeholder rule (else the
   glyph inherits 50%/opacity .6 and mis-sizes). The sparkle (action) keeps a soft disc; the
   lock (state) is a bare cream glyph with a shadow — his call, no disc. */
.tile .img .tilestate { position:absolute; left:6px; bottom:6px; z-index:3;
  display:flex; align-items:center; justify-content:center; }
.tile .img .tilestate svg { width:15px; height:15px; opacity:1; }
.tile .img .tilestate-polish { width:25px; height:25px; border-radius:50%;
  background:var(--tint); box-shadow:0 1px 3px rgba(20,16,10,.22); }
.tile .img .tilestate-polish svg { fill:var(--accent); stroke:none; }
/* s83 (his call): the off-the-rede lock wears the Peças padlock's SHAPE — solid body, round
   shackle, keyhole, 18px — in CREAM, no halo. Its keyhole is a REAL cut (evenodd), so the photo
   shows through (the Peças one fakes it with the page colour). */
.tile .img .tilestate-off { color:#FBF7F0; }
.tile .img .tilestate-off svg { width:18px; height:18px; }

/* Search-echo pills (FAB report F1) — what the brief/voice parse understood, each
   removable. Search-echo, not a facet form. */
.echopills { display:flex; flex-wrap:wrap; align-items:center; gap:7px; margin:8px 2px 12px; }
.echopills-lbl { font-size:12px; color:var(--ink-faint); margin-right:2px; }
.epill { display:inline-flex; align-items:center; gap:6px; font-size:12.5px; color:var(--accent);
  background:color-mix(in srgb, var(--accent) 9%, var(--paper)); border-radius:999px;
  padding:5px 11px; text-decoration:none; -webkit-tap-highlight-color:transparent; }
.epill-x { font-size:14px; line-height:1; opacity:.65; }
/* the fit pill — size is the co-primary sourcing axis, tinted terracotta to stand apart */
.epill-size { color:var(--terra); background:color-mix(in srgb, var(--terra) 11%, var(--paper)); }
.epill:active { opacity:.7; }
.sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }

/* A Mesa — the sourcing workbench (s11): search-all → pull → prove/look/orçamento */
.mesanote { text-align:left; margin:2px 2px 14px; }
.mesasearch { display:flex; align-items:center; gap:10px; background:var(--paper);
  border:1px solid var(--line-2); border-radius:12px; padding:11px 14px; margin-bottom:14px; }
.mesasearch svg { width:17px; height:17px; stroke:var(--ink-faint); stroke-width:1.8; fill:none;
  stroke-linecap:round; flex:none; }
.mesasearch input { flex:1; border:none; background:none; font-family:var(--sans); font-size:16px;
  color:var(--ink); outline:none; padding:0; -webkit-appearance:none; appearance:none; }
/* the deck — the other, by-eye way to fill the table; a permanent verb under search */
.mesadeck { display:flex; align-items:center; gap:12px; text-decoration:none; color:var(--ink);
  border:1px solid var(--line); border-radius:12px; padding:12px 14px; margin:-4px 0 16px;
  background:var(--card); }
.mesadeck:active { background:var(--paper-2); }
.mesadeck-ic { flex:none; width:34px; height:34px; border-radius:var(--r-ctl); background:var(--paper-2);
  display:grid; place-items:center; color:var(--accent); }
.mesadeck-ic svg { width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; }
.mesadeck-body { flex:1; min-width:0; }
.mesadeck-body b { display:block; font-size:14.5px; font-weight:600; }
.mesadeck-body small { display:block; font-size:12px; color:var(--ink-soft); margin-top:1px; }
.mesadeck-chev { flex:none; width:18px; height:18px; stroke:var(--ink-faint); stroke-width:1.8;
  fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* voice-confirm (#29): "here's what I heard" — the query as a preview before searching */
.mesaconfirm { background:var(--sand); border:1px solid var(--line-2); border-radius:12px;
  padding:14px 16px; margin:2px 0 14px; display:flex; flex-direction:column; gap:11px; }
.mesaconfirm-lbl { font-size:13px; color:var(--ink-soft); }
.mesaconfirm .echopills { margin:0; }
.mesaconfirm .epill { padding:5px 12px; }
.mesago { align-self:flex-start; margin:0; }
.bench { background:#F7F6F3; border-radius:15px; padding:13px 14px; margin-top:4px;
  box-shadow:0 2px 6px rgba(63,55,45,.05), 0 12px 26px -10px rgba(63,55,45,.16); }
.bench-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.bench-n { font-size:11.5px; letter-spacing:.08em; color:var(--ink-soft); font-weight:500; }
.bench-tray { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:12px; }
.bench-it { position:relative; }
.bench-it a { display:block; width:52px; aspect-ratio:2/3; border-radius:6px; overflow:hidden;
  background:var(--paper-2); border:1px solid var(--line); }
.bench-it img { width:100%; height:100%; object-fit:cover; display:block; }
.bench-it svg { width:100%; height:100%; stroke:var(--ink-faint); stroke-width:1.2; fill:none; padding:8px; box-sizing:border-box; }
.bench-it form button { position:absolute; top:-6px; right:-6px; width:20px; height:20px; border-radius:50%;
  border:none; background:var(--ink); color:var(--paper); font-size:12px; line-height:1; cursor:pointer;
  display:grid; place-items:center; padding:0; }
.bench-acts { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.bench-act { display:inline-flex; align-items:center; justify-content:center; gap:8px; padding:11px 8px;
  border:1px solid var(--line-2); border-radius:10px; background:var(--paper); font-family:var(--sans);
  font-size:13px; font-weight:500; color:var(--ink); text-decoration:none; cursor:pointer;
  -webkit-appearance:none; appearance:none; width:100%; box-sizing:border-box; }
.bench-act svg { width:16px; height:16px; stroke:currentColor; stroke-width:1.6; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.bench-act.go { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.bench-acts form { display:contents; }
/* The workbench lineup (mesa v2): zone reels + accessories + a bottom action bar.
   Reels/reelpiece/reelimg (with the checked green ring) are reused from compose. */
.lineup { margin-top:6px; }
/* A1 rail: chosen-outfit count + rental total (left), Sortear shuffle (right). */
/* Title row: "a mesa." on the left, the running count · rental total on the right. */
.mesatitle { display:flex; align-items:baseline; justify-content:space-between; gap:12px; }
.mesatitle h1 { white-space:nowrap; }
.lineup .slabel { margin:18px 2px 10px; }
.lineup .slabel.accslabel { text-transform:none; letter-spacing:.02em; font-size:11px; color:var(--ink-soft);
  border-top:0.5px solid var(--line); padding-top:14px; display:flex; align-items:baseline; }
/* s80: the accessory count on the right of the title row, matching the carousel chevron count (.si-rail-n) */
.accslabel .accs-n { margin-left:auto; font-family:var(--sans); font-size:10px; font-weight:700; line-height:1; color:var(--ink-faint); }
/* s75 (his call): the 'Acessórios' word wears the acabamentos title font (.phaselabel);
   the '· toque pra somar' beside it stays the quiet accslabel style. */
.accslabel .accs-ttl { text-transform:uppercase; letter-spacing:.09em; font-weight:600; color:var(--ink-faint); }
.reelacc .reelimg { aspect-ratio:1; }
/* The machine is ONE white card; each row is [ inset grey square image | white info
   side ], rows split by hairlines. HEIGHT-DRIVEN: JS sets --winH = viewport ÷ zones so
   the whole stack fits and Sortear flips every slot at once. */
.machine { width:auto; margin:4px 0 0; background:var(--paper); border:0.5px solid var(--line-2);
  border-radius:16px; overflow:hidden; box-shadow:0 1px 4px rgba(40,28,48,.06); }
/* Phase 2 (finishers) scrolls below at a fixed comfortable row height, not screen-fit. */
.machine2 { --winH:126px; }
.phaselabel { margin:18px 4px 8px; font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600; }
.slotframe { display:flex; align-items:stretch; height:var(--winH,200px); border-top:0.5px solid var(--line); }
.slotframe:first-child { border-top:none; }
/* A zone leaves the LOOK by collapsing — the ⊖ on its info side (zhidden), or covered
   by a full-body 'cima' pick (covered). Pieces stay on the bench; a chip below the
   machine brings the zone back. No 'nenhuma' card — a zone is in the look or gone. */
.slotframe.zhidden, .slotframe.covered { display:none; }
.machine.mempty { display:none; }
/* The restore chips — one '+ label' per collapsed zone, under its machine. */
.zonechips { display:flex; flex-wrap:wrap; gap:8px; margin:10px 2px 0; }
.zonechips:empty { display:none; margin:0; }
.zchip { display:inline-flex; align-items:center; gap:5px; padding:7px 13px; border-radius:20px;
  background:var(--paper); border:1px solid var(--line-2); color:var(--ink-soft);
  font-size:12.5px; font-weight:600; font-family:var(--sans); cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.zchip b { color:var(--accent); font-weight:700; }
.zchip:active { background:var(--paper-2); }
.zchip:disabled { opacity:.55; cursor:default; }
/* The ⊖ hide control — quiet, top-right corner of the info side. */
.slothide { position:absolute; top:5px; right:5px; width:28px; height:28px; display:grid;
  place-items:center; background:none; border:none; padding:0; color:var(--ink-faint);
  cursor:pointer; -webkit-appearance:none; appearance:none; -webkit-tap-highlight-color:transparent; }
.slothide svg { width:16px; height:16px; stroke:currentColor; stroke-width:1.6; fill:none; stroke-linecap:round; }
.slothide:active { color:var(--ink-soft); }
.slotwin { position:relative; flex:none; height:calc(var(--winH,200px) - 20px); width:calc(var(--winH,200px) - 20px);
  margin:10px; }
/* s81: NO rounded overflow:hidden clip wrapped around the .slot scroller any more — iOS Safari
   half-painted cards under it (a cream strip over a fine image). Each card rounds ITSELF. */
.slot { display:flex; overflow-x:auto; position:relative; height:100%; scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch; }
.slot::-webkit-scrollbar { display:none; }
.slotpiece { flex:0 0 100%; height:100%; scroll-snap-align:center; cursor:pointer; position:relative; }
.slotpiece.cap-out { display:none; }   /* s78: beyond the window cap — reachable via the rail, not the swipe */
.slotpiece input { position:absolute; opacity:0; width:0; height:0; }
/* long-press 'Tirar da mesa' (in place): the shared hold-ring overlays the piece. */
.slotpiece.holding .hold-ring { display:flex; }
.reelpiece .reelimg { position:relative; }
.reelacc.holding .hold-ring { display:flex; }
.slotimg { display:flex; height:100%; width:100%; overflow:hidden; border-radius:12px; background:var(--paper-2); }
.slotimg img { width:100%; height:100%; object-fit:cover; display:block; }
/* Square carousel fit: compact items crop to fill, tall items shrink to fit whole. */
.slotimg img.sq-cover { object-fit:cover; }
.slotimg img.sq-contain { object-fit:contain; }
.slotimg > svg { width:44px; height:56px; margin:auto; opacity:.4; stroke:var(--ink-faint); stroke-width:1.3; fill:none; }
/* Info side (right of the image): the pin+position pill on top, then the tap-to-ficha
   block (category label · piece name · price), a chevron pinned at the right edge. */
.slotside { flex:1; min-width:0; position:relative; display:flex; flex-direction:column;
  justify-content:center; gap:7px; padding:12px 32px 12px 6px; }
/* The pill IS the pin control: green, our pushpin glyph + the slot position (1/5); tap
   to lock so Sortear skips it (deeper green when pinned). */
.slottag { align-self:flex-start; display:inline-flex; align-items:center; gap:5px;
  background:transparent; color:var(--ink); font-size:11px; letter-spacing:.02em; font-weight:600;
  padding:4px 9px; border:1px solid var(--line-2); border-radius:20px; font-family:var(--sans); cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.slottag [data-slotpos]:empty { display:none; }
.stpin { display:block; width:12px; height:12px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* Pinned = the plum accent (the app's one "on" color — matches every other on-chip and
   the sibling tomesa pin). Neutral outline at rest, so color marks the state change. */
.slotframe.pinned .slottag { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.slotframe.lone .slottag { display:none; }
.slotinfo { display:flex; flex-direction:column; gap:3px; text-decoration:none; color:var(--ink);
  -webkit-tap-highlight-color:transparent; }
.slotinfo:active { opacity:.55; }
.si-name { font-size:13px; font-weight:700; color:var(--ink); line-height:1.3;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:hidden; }
/* s78: the dead ‹ chevron became a real ▾ toggle for the per-zone rail (his 'ver todas').
   Down at rest (expands below), flips up when the rail is open; hidden for a lone pin. */
.si-rail { position:absolute; right:2px; top:50%; transform:translateY(-50%); width:30px; height:34px;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:0; border:none;
  background:none; padding:0; cursor:pointer; color:var(--ink-faint); -webkit-tap-highlight-color:transparent; }
/* s78 (his call): the total pinned to this zone rides ON the opener — a quiet count (not an
   alert badge) that says how many the rail holds; only shown when there's overflow past the
   window cap, so the number itself signals 'more here than you can swipe'. Live-updated. */
.si-rail-n { font-family:var(--sans); font-size:10px; font-weight:700; line-height:1; color:var(--ink-faint); }
.si-rail svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; transition:transform .18s ease; }
.si-rail:active { color:var(--ink); }
.slotframe.railopen .si-rail { color:var(--accent); }
.slotframe.railopen .si-rail svg { transform:rotate(180deg); }
.slotframe.lone .si-rail { display:none; }
/* the rail panel: a scannable thumb strip of every piece pinned to the zone, dropped under
   the row. paper-2 + a hairline top so it reads as an inset shelf, not part of the card. */
.slotrail[hidden] { display:none; }
/* s78 (his call): the rail reads as a soft ROUNDED shelf, not a hard-cropped band — round all
   four corners + clip, a hair of margin so it floats under the row, and generous side padding so
   the first thumb is inset on open while a thumb peeks (soft-clipped by the corner) on the right. */
/* s83 (his call): the rail opens on the CARD's own cream, framed by a light hairline — not a
   darker block inside the card. */
.slotrail { margin:3px 0 7px; background:var(--card); border:1px solid var(--hair); border-radius:14px; overflow:hidden; }
/* The inset is a MARGIN on the reel, not padding — iOS WebKit drops the inline padding of a
   horizontal overflow-x scroller, so the paper-2 panel shows through the margin as a frame on
   all four sides (first thumb inset on open; a thumb peeks, soft-clipped, 14px in on the right). */
.slotrail-reel { margin:12px 14px; display:flex; gap:8px; overflow-x:auto; scroll-snap-type:x proximity;
  -webkit-overflow-scrolling:touch; }
.slotrail-reel::-webkit-scrollbar { display:none; }
.slotrail-thumb { flex:0 0 calc((100% - 24px) / 4); padding:0; border:none; background:none; cursor:pointer;
  scroll-snap-align:start; -webkit-tap-highlight-color:transparent; }
.slotrail-img { position:relative; display:flex; aspect-ratio:1; border-radius:10px; overflow:hidden;
  background:var(--paper-2); box-shadow:0 0 0 1px var(--line-2) inset; }
.slotrail-img img { width:100%; height:100%; object-fit:cover; display:block; }
.slotrail-img img.sq-contain { object-fit:contain; }
.slotrail-img > svg { width:32px; height:40px; margin:auto; opacity:.4; stroke:var(--ink-faint); stroke-width:1.3; fill:none; }
.slotrail-thumb.on .slotrail-img { box-shadow:0 0 0 2px var(--accent) inset; }
.slotrail-img .reelnet { position:absolute; right:4px; top:4px; }
.titletop { padding-top:18px; }
/* Sortear — a full-width bar under the machine (shuffle every unpinned slot). */
.sortearbar { display:flex; align-items:center; justify-content:center; gap:12px; width:100%; margin:12px 0 0;
  background:var(--paper); border:0.5px solid var(--line-2); border-radius:14px; padding:15px 16px;
  cursor:pointer; -webkit-appearance:none; appearance:none; box-shadow:0 1px 4px rgba(40,28,48,.06); }
.sortearbar[hidden] { display:none; }
.sortearbar:active { background:var(--paper-2); }
.sortearbar svg { flex:none; width:22px; height:22px; stroke:var(--accent); stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.sortearbar-body { display:flex; flex-direction:column; text-align:center; min-width:0; }
.sortearbar-body b { font-size:15px; font-weight:700; color:var(--accent); }
.sortearbar-body small { font-size:12px; color:var(--ink-soft); margin-top:1px; }
.provarpanel { margin-top:14px; }
.provarpanel[hidden] { display:none; }
/* The one prova door (s60, collapsed from the s59 two-door split): 'Provar de novo' /
   '✦ Provar em alguém', full-width. */
.provargen { display:flex; flex-direction:column; gap:9px; margin-top:2px; }
.provargen[hidden] { display:none; }
.provargen .lineup-provar { flex:none; width:100%; display:flex; align-items:center;
  justify-content:center; border:1px solid transparent; }
/* At the prova cap (s59): a calm heads-up (amber family, not alarm) replacing the doors. */
.provacap { display:flex; align-items:center; gap:9px; margin:13px 0; padding:13px 14px;
  border-radius:12px; background:var(--chip-warn-bg); color:var(--chip-warn-ink);
  font-size:12.5px; line-height:1.4; }
.provacap[hidden] { display:none; }   /* author display:flex overrides the hidden attribute's UA display:none — restore it */
.provacap svg { flex:none; width:18px; height:18px; fill:none; stroke:currentColor;
  stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
/* The takeover panel's close header (s32): title gives the panel an identity, ✕ is
   where the eye goes to dismiss. The panel hides the navbar, so this is the exit. */
.panelhead { display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
.panelhead-t { font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:-.01em; color:var(--ink); }
.panelhead-x { border:none; background:none; font-size:20px; line-height:1; color:var(--ink-faint);
  cursor:pointer; padding:4px 8px; margin:-4px -8px -4px 0; -webkit-tap-highlight-color:transparent; }
.panelhead-x:active { color:var(--ink); }
/* Each Mesa verb is its own <form>, but must not perturb the lineup layout — the
   form box vanishes so its panel/button lays out exactly as before. */
.verbform { display:contents; }
.provarphoto { display:flex; align-items:center; justify-content:center; gap:8px; margin-top:10px;
  padding:12px; border:1px dashed var(--line); border-radius:12px; color:var(--muted);
  font-family:var(--sans); font-size:14px; cursor:pointer; text-align:center; }
.provarphoto.on { border-style:solid; border-color:var(--accent); color:var(--ink); }
/* 'Em quem?' — O ESCOLHIDO (s27): the chosen person wears the 104px charface
   square (the character card's geometry); the roster is a WRAPPING grid shown
   only while choosing — overflow is structurally impossible. */
.quemhead { display:flex; gap:16px; align-items:center; }
.quemhead[hidden] { display:none; }
.quemface { width:104px; height:104px; flex:none; border-radius:14px; overflow:hidden;
  background:var(--paper-2); border:2px solid var(--line); display:grid; place-items:center; }
.quemface img { width:100%; height:100%; object-fit:cover; }
.quemface img:not([src]) { display:none; }
.quemmeta { display:flex; flex-direction:column; gap:7px; min-width:0; }
.quemlbl { font-size:11px; letter-spacing:.14em; color:var(--ink-faint); text-transform:uppercase; }
.quemnm { font-family:var(--sans); font-size:16px; font-weight:600; color:var(--ink); }
.quemnm:empty { display:none; }
.quemdoors { display:flex; gap:8px; flex-wrap:wrap; margin-top:2px; }
.whorow { display:flex; flex-wrap:wrap; gap:12px; padding:2px 2px 6px; }
.whorow[hidden] { display:none; }
.whochip { position:relative; flex:none; width:64px; display:flex; flex-direction:column;
  align-items:center; gap:4px; cursor:pointer; }
.whochip input { position:absolute; opacity:0; pointer-events:none; }
/* actor faces are SQUARES with rounded corners everywhere in the pipeline (the
   charface doctrine, s23b: 14px @104 → ~11px @56); circles = USER avatar only */
.whoface { width:56px; height:56px; border-radius:11px; overflow:hidden; background:var(--paper-2);
  border:2px solid var(--line); display:grid; place-items:center; }
.whoface img { width:100%; height:100%; object-fit:cover; }
/* Chosen = the VIVID one (s27, his call — the accent ring was noise): when someone
   is checked, everyone else recedes; the cabeçalho's position+size already say
   "chosen", so no face wears a ring anywhere. */
.whochip { transition:opacity .15s; }
.whorow:has(.whochip.on) .whochip:not(.on) { opacity:.55; }
.whoface-add { border-style:dashed; color:var(--muted); font-size:24px; font-weight:300; line-height:1; }
.whoface-add svg { width:22px; height:22px; stroke:currentColor; stroke-width:1.7; fill:none; }
.whochip-new.on .whoface { border-style:solid; border-color:var(--ink); }
/* The file inputs in the nova-foto/câmera chips are REAL transparent overlays
   (ios-file-input-picker-anchor): full-cover + hit-testable so iOS anchors the picker
   to the tap, not the screen top. The radio inputs above stay label-driven. */
.whochip-new input[type=file] { inset:0; width:100%; height:100%; pointer-events:auto; cursor:pointer; }
.whonm { max-width:64px; font-family:var(--sans); font-size:11px; color:var(--ink-soft);
  text-align:center; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.whochip .hold-ring { position:absolute; top:6px; left:10px; width:44px; height:44px; border-radius:50%; }
.whohint { margin:8px 2px 0; font-family:var(--sans); font-size:12.5px; color:var(--muted); }
.whohint[hidden] { display:none; }
.whohint b { color:var(--ink-soft); font-weight:600; }
/* The desc door STANDS (s27, calm machine) — a permanent pill, never an
   apparition. #whoRow-scoped to out-specify .tryonform button (the cascade
   family), same as .whoswap below. */
#whoRow ~ .whodesc-toggle { display:inline-block; width:auto; align-self:flex-start; margin-top:10px; font-size:12.5px;
  font-family:var(--sans); color:var(--ink-soft); border:1px solid var(--line-2);
  border-radius:var(--r-ctl); padding:7px 14px; background:var(--paper); text-decoration:none;
  cursor:pointer; -webkit-appearance:none; appearance:none; }
/* trocar pessoa… — an nspill-costume TOGGLE in the cabeçalho. Scoped .quemdoors
   .whoswap on purpose: .tryonform button (0-1-1) out-specifies a lone class, and
   the panel mounts in rooms with and without .tryonform (the cascade family). */
.quemdoors .whoswap { align-self:center; flex:none; width:auto; font-size:12.5px;
  font-family:var(--sans); color:var(--ink-soft); border:1px solid var(--line-2);
  border-radius:var(--r-ctl); padding:7px 14px; background:var(--paper); text-decoration:none;   /* s70: the app's control radius */
  cursor:pointer; -webkit-appearance:none; appearance:none; }
/* "Duas portas" (s35b): the roster above is RECOGNITION (reuse a known face); the two ways
   to make a NEW person — Foto / Descrever, + Câmera on Android — drop here as an organized
   labeled pair. display stays at plain-class specificity so the id-gated #provarCameraLabel
   (display:none, revealed by html.os-android) still hides the camera door on iOS. */
.whonew { margin-top:16px; }
.whonew[hidden] { display:none; }
.whonew-lbl { font-family:var(--sans); font-size:10.5px; font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-faint); margin:0 2px 9px; }
.whodoors { display:flex; flex-wrap:wrap; gap:9px; }
.whodoor { position:relative; flex:1 1 130px; display:flex; align-items:center; gap:9px;
  padding:11px 12px; border:1px solid var(--line-2); border-radius:var(--r-ctl); background:transparent;
  color:var(--ink); font-family:var(--sans); text-align:left; cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.whodoor.on { border-color:var(--accent); background:var(--tint); }
.whodoor:active { background:var(--paper-2); }
.whodoor input[type=file] { position:absolute; inset:0; width:100%; height:100%; opacity:0;
  pointer-events:auto; cursor:pointer; }
/* s75 (his call): the disc + glyph are ONE svg (not a CSS circle + a separate inner svg) so
   they rasterise as a single unit — a separate svg on a fractionally-positioned door (flex
   widths, ×3 phone) snaps to a different sub-pixel grid and the glyph drifts off the disc
   (the glyph-in-disc trap, [[glyph-in-disc-centering]]). Each glyph is bbox-centred at 16,16. */
.whodoor-ic { flex:none; width:32px; height:32px; }
.whodoor-ic svg { width:32px; height:32px; display:block; }
.whodoor-ic .wd-disc { fill:var(--tint); stroke:none; }
.whodoor-ic .wd-gl { fill:none; stroke:var(--accent); stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.whodoor-t { min-width:0; }
.whodoor-t b { display:block; font-size:13px; font-weight:600; letter-spacing:-.01em; }
.whodoor-t small { display:block; font-size:11px; color:var(--ink-faint); margin-top:1px; }
/* the desc box is the Descrever door's expanded content — a tinted inset that slides out
   below it, never a textarea jammed against the doors + the Gerar button (s35b). */
#descWrap { margin-top:11px; padding:10px; background:var(--tint); border-radius:var(--r-ctl); }
#descWrap textarea { background:var(--card); }

.lineup-generate { width:100%; margin-top:10px; border:none; border-radius:12px; padding:14px;
  background:var(--accent); color:var(--on-accent); font-family:var(--sans); font-size:15px;
  font-weight:700; cursor:pointer; }
/* while a render runs the button just greys out (the gerando card's × is the cancel). */
.lineup-generate:disabled { opacity:.5; cursor:default; }
.lineupbar { display:flex; gap:8px; align-items:stretch; margin-top:16px; }
/* s59: while a prova generates the whole console collapses to the beat — hide these as
   units. display:flex/block would beat the UA [hidden] rule, so honor it explicitly. */
.lineupbar[hidden], .mch-clearform[hidden] { display:none; }
.lineup-provar { flex:1.4; display:inline-flex; align-items:center; justify-content:center; gap:6px;
  border:1px solid var(--line-2); border-radius:12px; padding:12px 8px; background:var(--on-accent);
  color:var(--accent); font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
/* s78 (his call): the ✦ door glyph became the ficha's two-glint sparkle SVG (same paths as
   .heropolish-spark), painted pink (var(--dot)). It is a PERSISTENT DOM child beside a label
   span, so the busy/label churn only rewrites the span's text and the sparkle survives. */
/* s78 (his call): OPTICALLY centre the label. The sparkle+gap sit left of the text, so a
   geometrically-centred [✦ text] group reads right-heavy (the eye centres the text mass). A
   -14px pull on the sparkle shifts the whole group left ~7px — the text lands visually centred
   with the sparkle in a comfortable left gutter, not jammed to the edge. */
.lineup-provar-spark { flex:none; width:15px; height:15px; margin-left:-14px; fill:var(--dot); stroke:none; }
.lineup-provar-lbl { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lineup-provar.has-who { font-size:13px; }
/* s75 — while a non-prova render runs the ✦ door greys with an honest label (no false beat). */
.lineup-provar.busy, .lineup-provar:disabled { background:var(--paper-2); color:var(--ink-faint); cursor:default; font-size:13px; }
.lineup-provar.busy .lineup-provar-spark, .lineup-provar:disabled .lineup-provar-spark { fill:var(--ink-faint); }
/* Look-page doorway (s41): the same toggle, but standalone (no flex row) — full width,
   its own breathing room above the collapsed composer. */
.lookprovar-toggle { flex:none; width:100%; margin-top:2px; }
/* OPEN state = the closer (s35b, "✕ Fechar"): a quiet ghost, so the primary CTA is the
   Gerar/Salvar button INSIDE the panel, not the close. Both toggles read the same when open. */
.lineup-provar.on, .lineup-act.on { background:transparent; color:var(--ink-soft);
  border:1px solid var(--line-2); font-weight:600; }
.lineup-act { flex:1; border:1px solid var(--accent); border-radius:12px; padding:12px 8px;
  background:var(--on-accent); color:var(--accent); font-family:var(--sans); font-size:14px; font-weight:600;
  cursor:pointer; -webkit-appearance:none; appearance:none; }
/* s75 (his call): Salvar is the filled primary (plum + cream); Provar em alguém is the inverse
   outline beside it. `:not(.on)` lets the open-state ghost (.lineup-act.on) still win on toggle. */
#salvarToggle:not(.on) { background:var(--accent); color:var(--on-accent); border-color:var(--accent); }
#salvarToggle:not(.on):active { background:var(--accent-press); border-color:var(--accent-press); }
/* the couldn't-fill note from a worded fill — a quiet line, never a modal */
.mesamiss { margin:2px 0 10px; font-family:var(--sans); font-size:13px; color:var(--muted); }

/* ── THE CONSOLE (s35b): the montage instrument as ONE lifted card, so the carousel,
   acabamentos, acessórios and verbs stop floating apart — the rede shading system on the
   Mesa. SKIN ONLY: no JS hook (.lineup/.machine/.slotframe/.lineupbar/panels) changes. ── */
/* rede's section eyebrow — rose dot-tick + uppercase — for "montar" and "meus looks" */
.mesasec-lbl { position:relative; display:flex; align-items:center; gap:8px; margin:26px 2px 12px;
  font-size:11px; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); }
.mesasec-n { color:var(--accent); letter-spacing:.06em; }
/* a place-link (or quiet mode-toggle button) riding a section label's far right (s45:
   'lookbooks ›' on meus looks; 'reordenar' on a lookbook) — reads as a link, not a
   sibling label: lowercase, accent, quiet */
.mesasec-go { margin-left:auto; font-size:12.5px; font-weight:500; letter-spacing:.02em;
  text-transform:none; color:var(--accent); text-decoration:none; border:none;
  background:none; padding:0; font-family:var(--sans); cursor:pointer; }
.mesasec-go:active { opacity:.6; }
/* acervo grouping (s35c): filters belong to the header, so tighten the gap ABOVE the
   filtrar block (title→filtrar) and open the gap BELOW it (card→peças) — chrome groups
   up with the title, the peças content sets itself apart. A<B (18 vs 40), not A=B */
.acsec-pecas { margin-top:26px; flex-wrap:wrap; row-gap:6px; }   /* s49/s50: past what fits, the actions drop to a second line, never off-screen; s62: tightened from 40 — the gap below the swatch row read as too much */
.acsec-count { display:inline-flex; align-items:center; gap:8px; white-space:nowrap; }
.acsec-acts { margin-left:auto; display:inline-flex; align-items:center; gap:10px; }
/* na rede / value ride the Peças eyebrow as one stat cluster; each segment stays a
   non-breaking unit so it never wraps mid-token at phone width */
.mesasec-seg { white-space:nowrap; }

.mesaconsole { background:var(--card); border-radius:var(--r-card); box-shadow:0 6px 22px var(--shadow);
  overflow:hidden; padding-bottom:14px; margin-top:16px; }
/* the gradient head caps the console + carries the montar context (folds the montarctx bar) */
.mconsole-head { display:flex; align-items:center; gap:10px; padding:9px 14px; background:var(--grad); color:#fff; }
.mch-ic { flex:none; width:30px; height:30px; border-radius:50%; background:rgba(255,255,255,.16); display:grid; place-items:center; }
.mch-ic svg { width:16px; height:16px; stroke:#fff; fill:none; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.mch-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.mch-body b { font-size:14px; font-weight:600; letter-spacing:-.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mch-body small { font-size:11px; color:rgba(255,255,255,.82); }
.mch-pal { flex:none; display:flex; gap:3px; }
.mch-pal span { width:11px; height:11px; border-radius:50%; box-shadow:inset 0 0 0 1px rgba(255,255,255,.25); }
.mch-x { flex:none; color:rgba(255,255,255,.85); text-decoration:none; font-size:22px; line-height:1; padding:2px 6px; }
/* Tirar tudo da mesa (s77): the acervo's pin-with-✕ glyph, reused verbatim, painted CREAM
   for the always-dark plum header (like the header's own hardcoded #fff text). Reuses
   .pinclear/.pinclear-glyph/.pinclear-x; only the two colours are overridden. */
.mch-clearform { flex:none; display:inline-flex; align-items:center; margin:0; }
.pinclear.mch-clear { color:#F4EEE6; }
.pinclear.mch-clear .pinclear-x { color:#F4EEE6; }
/* inner sections sit ON the card: side-inset via .lineup padding; the machine sheds its own
   card chrome (the console IS the card now); the verbs become a hairline-topped footer. */
.mesaconsole > .lineup { margin:0; padding:0 14px; }
.mesaconsole .machine { margin:12px 0 0; border:none; box-shadow:none; background:transparent; }
.mesaconsole .machine .slotframe { border-top-color:var(--hair); }
.mesaconsole .lineup .slabel.accslabel { border-top-color:var(--hair); }
/* s77 (his call): 'acabamentos' gets the SAME faint hairline the 'Acessórios' title carries,
   so the two section headers read as a matched pair. */
.mesaconsole .phaselabel { border-top:0.5px solid var(--hair); padding-top:14px; }
/* s75 (his call): the verbs get a 'criar um look' eyebrow (same title font as acabamentos/
   acessórios). The title rides as a full-width first child of the flex row (flex-wrap). s77:
   the eyebrow now STAYS when a composer opens — only .lineupacts (the toggle row) hides — so
   the panel opens under a persistent title; and it wears the SAME faint hairline the
   acabamentos/Acessórios titles carry, so the section reads as a matched sibling. */
.mesaconsole .lineupbar { margin:18px 0 0; padding-top:14px; border-top:0.5px solid var(--hair); flex-wrap:wrap; }
.lineuphead { flex:0 0 100%; margin:0 0 2px; font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  font-weight:600; color:var(--ink-faint); }
/* ---- SOURCING MODE (s35f): the search results ARE the landing ---- */
.mesa-results .tilewrap { position:relative; }
/* photo-first result tiles: soft canon corners (the museum 2px is retired here),
   size chip on the photo, owner in accent; the .pull '+' died with its reload */
.mesa-results .tile .img { border-radius:var(--r-card); border:none; position:relative; }
.mesa-results .netowner { color:var(--accent); font-weight:600; }
.srchlbl { display:flex; align-items:center; }
.srchback-row { display:inline-block; margin:12px 0 0; color:var(--accent); text-decoration:none; font-size:13px; }
.srchback { margin-left:auto; text-transform:none; letter-spacing:.01em; font-size:12.5px;
  font-weight:600; color:var(--accent); text-decoration:none; }
.srchhero { font-size:21px; font-weight:700; letter-spacing:-.01em; margin:2px 2px 0; }
/* the benchline: the bench made visible while sourcing — live count + the next verb */
/* s83 (his call): the bench line breathes BELOW as much as above — the grid used to butt it (4px). */
.benchline { display:flex; align-items:center; gap:6px; margin:16px 0 14px; padding:11px 13px;
  background:var(--tint); border-radius:var(--r-ctl); color:var(--ink); font-size:13.5px;
  font-weight:600; text-decoration:none; font-variant-numeric:tabular-nums; }
.benchline b { color:var(--accent); }
.benchline-go { margin-left:auto; color:var(--accent); }
/* A draft's own row (s50): the amber warning dress, one verb — Confirmar. */
.draftrow { display:flex; align-items:center; gap:11px; margin-top:16px; padding:11px 13px;
  border:1px solid color-mix(in srgb, var(--warn) 55%, var(--line-2)); border-radius:12px;
  background:color-mix(in srgb, var(--warn) 6%, var(--paper)); }
.draftrow > svg:first-child { width:20px; height:20px; flex:none; fill:none; stroke:var(--warn); stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
.draftrow .rederow-body { flex:1; min-width:0; }
.draftrow-ok { flex:none; border:0; border-radius:10px; padding:9px 14px; background:var(--accent); color:var(--on-accent);
  font:inherit; font-weight:600; font-size:14px; -webkit-tap-highlight-color:transparent; }
.draftrow-ok:active { background:var(--accent-press); }
a.redehint { text-decoration:none; -webkit-tap-highlight-color:transparent; }
a.redehint b { font-weight:600; }
.mesalink { display:flex; align-items:center; gap:11px; margin-top:16px; padding:12px 13px;
  border:1px solid color-mix(in srgb, var(--accent) 45%, var(--line-2));
  border-radius:12px; background:color-mix(in srgb, var(--accent) 4%, var(--paper));
  text-decoration:none; -webkit-tap-highlight-color:transparent; }
.mesalink:active { background:color-mix(in srgb, var(--accent) 9%, var(--paper)); }
.mesalink > svg:first-child { width:20px; height:20px; color:var(--accent); flex:none; }
.mesalink .rederow-chev { stroke:var(--ink-faint); }
/* The TOGGLE variant (s45, one dress two honest edges): the rede piece's bench-pin
   wears the same row as the ficha's door, but a PIN on the right instead of the
   chevron — this one stays put (gather and keep browsing), it never navigates. */
.mesarow-form { margin:14px 0; }
button.mesalink { width:100%; margin-top:0; font-family:var(--sans); font-size:inherit;
  text-align:left; cursor:pointer; -webkit-appearance:none; appearance:none; color:var(--ink); }
/* s52p — the mesa toggle, TRIMMED (his call): one glyph (the pin), one line, fixed
   height, constant fill. State lives in the pin (outline → filled plum) + the label — no
   arrow (it contradicted 'na mesa'), no subtitle, no darker on-state. Shared by the ficha
   and the rede piece page, so both read the same. */
.mesalink--pin { display:flex; align-items:center; justify-content:center; gap:9px;
  min-height:46px; padding:0 14px; border:0; border-radius:12px; background:var(--tint);
  color:var(--ink); font-family:var(--sans); font-weight:600; cursor:pointer;
  width:100%; text-align:center; -webkit-appearance:none; appearance:none;
  -webkit-tap-highlight-color:transparent; }
/* s53 — the label was rendering at 16px: button.mesalink's `font-size:inherit` outweighs a
   plain `.mesalink--pin`, so it inherited the page size. Pin it to 14px with a two-class
   selector that wins, and trim the glyph to suit (his call: 'slightly smaller'). */
.mesalink.mesalink--pin { font-size:14px; }
.mesalink--pin:active { background:var(--tint-2); }
.mesalink.mesalink--pin .rederow-pin { width:17px; height:17px; flex:none; fill:none;
  stroke:var(--accent); stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
.mesalink--pin.on .rederow-pin { fill:color-mix(in srgb, var(--accent) 28%, transparent); }
.mesalink-inline { color:var(--accent); }
/* colour-tap browse — the archive's one filter: the colours present, as swatches.
   Tap = filter to that bucket; tap the ringed one = clear. Others dim when picked. */
/* Swatch row (s62): steady-size circles, CENTERED, capped at SIX per line (his call). max-width =
   6·34 + 5·9 = 249px; ≤6 colours just centre (the cap does nothing), 7+ wrap to a centred 2nd row.
   Order is untouched — it's spectral in color_buckets, independent of layout; the cap only moves the
   wrap point. The old per-count squeeze (.colorrow--nine) stays gone. */
.colorrow { display:flex; flex-wrap:wrap; justify-content:center; gap:9px; margin:4px auto 16px; max-width:249px; }
/* Editorial swatches (variant A): flat CIRCLES on the bare paper — a fixed comfortable size
   (they no longer stretch to fill the width), with a faint inset hairline for the near-white edge. */
.csw { width:34px; height:34px; aspect-ratio:1; border-radius:50%; flex:none;
  border:1px solid rgba(20,16,10,.08); box-shadow:inset 0 0 0 1px rgba(20,16,10,.05); transition:opacity .12s; -webkit-tap-highlight-color:transparent; }
.colorrow.picked .csw { opacity:.3; }
/* Selected: the accent ring (box-shadow paints outside the element). */
/* the chosen swatch's ring is ink (near-black), not the accent plum (s62, his call) */
.colorrow.picked .csw.on { opacity:1; box-shadow:0 0 0 2px var(--paper), 0 0 0 4px var(--ink); }
/* The near-white swatch (Branco) is almost the paper colour, so its faint hairline vanished
   when the row dimmed on a pick (s62, his catch). Give it a stronger edge, and dim it LESS than
   the coloured swatches so that edge survives — a coloured swatch reads at .3, a white one needs
   its ring to stay legible. */
.csw-light { border-color:rgba(20,16,10,.22); }
.colorrow.picked .csw-light { opacity:.6; border-color:rgba(20,16,10,.34); }
.csw:active { transform:scale(.92); }
/* Filtrar, editorial (variant A): the plum slab and the swatch card are both gone. The
   facet names read as quiet letterspaced caps split by hairline ticks, straight on the
   paper; the colours are flat circles below, and one rule closes the block. Chrome receded
   so the browse controls read as content, not as two stacked panels over the grid. */
.acfilters { background:none; box-shadow:none; border-radius:0; padding:0; margin-top:22px; }
/* Content-sized labels in ONE centered flex row with an even gap — NOT rigid ⅓ cells.
   Equal cells overflowed at phone width (a long facet like TAMANHO grew past its 80px cell
   and the boundary tick landed on the letters). Here every word keeps its natural width, the
   gap between any two is identical, and each tick sits dead-centre in that gap — so nothing
   collides and the group centres itself, pulled in from the edges. */
.acfilters .fchips { display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:8px 26px; margin:0 0 2px; padding:0; }
.acfilters .fchips .fchipwrap { flex:0 0 auto; min-width:0; display:flex; align-items:center; justify-content:center; position:relative; }
.acfilters .fchipwrap + .fchipwrap::before { content:""; position:absolute; left:-13px; top:50%;
  transform:translateY(-50%); width:1px; height:14px; background:var(--line-2); }
.acfilters .fchip { justify-content:center; background:none; border:none; border-radius:0;
  padding:12px 0; font-size:12.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-soft); font-weight:600; cursor:pointer; }
.acfilters .fchip:active { background:none; color:var(--accent); }
/* Active filters lift OUT of the caps row into their own wrapping chip row (s44): the four
   caps stay a stable single line that never overflows, and the selections read as removable
   plum chips that wrap cleanly — the spillover is designed-for, not an accident. */
.acfilters .facpills { display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px; margin:0 0 14px; }
.acfilters .facpill { display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:500;
  color:var(--accent); background:var(--tint); border-radius:var(--r-pill); padding:5px 12px; text-decoration:none; }
.acfilters .facpill-x { font-size:13px; line-height:1; opacity:.75; }
.acfilters .facpill:active { background:var(--tint-2); }
.acswcard { background:none; box-shadow:none; border-radius:0; padding:0 4px 8px; margin-top:6px; }
.acswcard .colorrow { margin:0 auto; }

.rlist { display:flex; flex-direction:column; }
.rrow { display:flex; align-items:center; gap:14px; padding:15px 2px; border-bottom:1px solid var(--line); text-decoration:none; color:var(--ink); }
.rmain { flex:1; min-width:0; }
.rclient { font-size:15px; font-weight:500; }
.rsub { font-size:12px; color:var(--ink-faint); margin-top:3px; }
.rside { display:flex; flex-direction:column; align-items:flex-end; gap:6px; flex:none; }
.rtotal { font-size:12.5px; color:var(--ink-soft); }
.badge { font-size:10.5px; letter-spacing:.08em; text-transform:uppercase; padding:3px 9px; border-radius:999px; border:1px solid var(--line-2); color:var(--ink-soft); white-space:nowrap; }
.badge.st-draft { color:var(--ink-faint); }
.badge.st-confirmed { color:var(--accent); border-color:var(--accent); }
.badge.st-picked_up { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }
.badge.st-returned { color:var(--ink-soft); border-color:var(--line-2); }
.badge.st-closed { color:var(--ink-faint); background:var(--paper-2); }
.badge.st-cancelled { color:var(--ink-faint); text-decoration:line-through; }
/* teste (s29) — the dress-rehearsal marker. Dashed, like the "not wired" tag in
   controle: a deliberate, calm state, never an alarm. */
.badge.st-teste { color:var(--ink-faint); border-style:dashed; margin-left:6px; }

/* terms + privacy (s29) — a reading page: measure capped, headings that breathe */
.termos { max-width:44rem; }
.termos h2 { font-size:15px; margin:26px 0 8px; letter-spacing:.01em; }
.termos p, .termos li { font-size:14.5px; line-height:1.62; color:var(--ink-soft); }
.termos ul { margin:8px 0 0; padding-left:20px; }
.termos li { margin-bottom:6px; }
.termos b { color:var(--ink); font-weight:600; }
.termos .btn { margin-top:4px; }
.onboard-terms { margin:14px 0 0; font-size:12px; line-height:1.5; color:var(--ink-faint); text-align:center; }
.onboard-terms a { color:var(--ink-soft); }
/* the explicit consent check (s31) — a real tap target, left-aligned with the form */
.onboard-termscheck { display:flex; align-items:flex-start; gap:10px; text-align:left;
  margin:16px 2px 0; cursor:pointer; color:var(--ink-soft); font-size:12.5px; }
.onboard-termscheck input { flex:none; width:19px; height:19px; margin:1px 0 0; accent-color:var(--accent); }
.termoslink { margin:22px 0 16px; font-size:13px; }
.termoslink a { color:var(--ink-faint); }

/* OWNER PILLS (s29) — "whose acervo" as a progressive filter over ONE ranked list,
   never as doors. Sits directly under the tier label, scrolls sideways rather than
   wrapping into a wall when the rede grows. */
.ownerpills { display:flex; gap:7px; margin:0 0 12px; padding:1px 2px 4px;
  overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.ownerpills::-webkit-scrollbar { display:none; }
/* padding matched to .nspill's box (31px) — the scope pills sit a few lines apart
   on this same page, and a 2px difference between them reads as a mistake */
.opill { flex:none; font-size:12.5px; font-family:var(--sans); color:var(--ink-soft);
  border:1px solid var(--line-2); border-radius:999px; padding:7px 13px;
  background:var(--paper); text-decoration:none; white-space:nowrap; }
.opill b { font-weight:600; color:var(--ink-faint); margin-left:3px; }
.opill.on { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }
.opill.on b { color:var(--on-accent); opacity:.75; }
.tierlabel small { font-weight:400; color:var(--ink-faint); text-transform:none; letter-spacing:0; }

/* the invite economy's user side (§4, wired s29): a visible, finite stack —
   scarcity is the point, so the count reads like currency, not like a warning */
.invcount { float:right; font-size:11.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-faint); border:1px solid var(--line-2); border-radius:999px; padding:2px 9px; }
.invsoon { margin:8px 2px 0; padding:11px 12px; border:1px dashed var(--line-2);
  border-radius:3px; color:var(--ink-faint); font-size:13px; text-align:center; }

/* the feedback door + the wallet-empty credits door (s29) — quiet, never a
   headline: they matter at exactly one moment and recede the rest of the time */
.feedbackdoor { display:flex; align-items:center; gap:11px; padding:11px 12px;
  margin:0 0 18px; background:var(--paper-2); border:1px solid var(--line);
  border-radius:3px; color:var(--ink); text-decoration:none; }
.feedbackdoor svg { width:20px; height:20px; flex:none; fill:none;
  stroke:var(--ink-soft); stroke-width:1.6; stroke-linecap:round; }
button.feedbackdoor { width:100%; text-align:left; font:inherit; cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.feedbackdoor span { font-size:14px; line-height:1.3; }
.feedbackdoor em { display:block; font-style:normal; font-size:12px; color:var(--ink-faint); margin-top:2px; }
/* saldodoor now wears .btn.primary (s32) — the recarga CTA is a real button per
   canon; this only carries spacing so the button style governs the look. */
.saldodoor { margin:6px 0 12px; }
/* The recarga button — the money-in door, the app's most important CTA. */
.recargabtn { margin-top:12px; }
/* Quiet recarga link in the Conta review-drawer: the chip is the pay-door, so here
   it's a demoted text link, not a co-equal primary button. */
.aiu-reclink { margin-top:12px; display:inline-block; background:none; border:none;
  padding:0; font:inherit; font-size:13px; font-weight:600; color:var(--accent);
  text-decoration:underline; text-underline-offset:2px; cursor:pointer; }

/* the borrower's side of a rede locação (s29) — her two verbs, full width */
.borrowacts { margin:18px 0 0; display:flex; flex-direction:column; gap:9px; }
.borrowacts .btn { width:100%; }
/* Cancelar a pedido is a quiet exit, never a competing button (s41): a muted text
   link that warms to danger on press. */
.borrowacts .btn.cancelped { border:none; background:none; color:var(--ink-faint);
  font-weight:400; padding:8px; }
.borrowacts .btn.cancelped:active { border:none; color:var(--danger); }

/* Borrower rede locação (s41 S/N rework) — the receipt reads as ONE grouped card,
   and status is a coloured line (grasped without decoding a badge). Mirrors the
   rede-pedir card language so the whole borrow flow speaks one dialect. */
.borroweyebrow { font-size:10.5px; font-weight:500; letter-spacing:.11em;
  text-transform:uppercase; color:var(--ink-faint); margin-bottom:7px; }
/* the Job value in the borrow card's meta — a tappable link to the job (s44) */
.joblink { color:var(--accent); text-decoration:none; }
.joblink:active { opacity:.6; }
.borrowrcpt { background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
  padding:13px 14px; box-shadow:0 8px 22px rgba(40,28,48,.10); margin-top:16px; }
.borrowrcpt .rilist { margin-top:2px; }
.borrowrcpt hr.rule { margin:12px 0; }
.borrowrcpt .meta { margin-top:2px; }
.status.st-accent { color:var(--accent); }
.status.st-warn { color:var(--warn); }
.status.st-ok { color:var(--ok); }

/* the teste opt-in on the two creation forms — a quiet line, never a headline */
.testeopt { display:flex; align-items:flex-start; gap:9px; margin:14px 2px 0; cursor:pointer; }
.testeopt input { margin-top:2px; flex:none; }
.testeopt span { font-size:13px; color:var(--ink-soft); line-height:1.35; }
.testeopt em { font-style:normal; color:var(--ink-faint); }

/* return clock (#27) — the rental-native strip: what's out and due back */
.retclock { display:flex; flex-direction:column; gap:12px; margin:6px 0 26px; }
.retgroup { border:1px solid var(--line); border-radius:11px; overflow:hidden; background:var(--paper); }
.retgroup.late { border-color:color-mix(in srgb, var(--danger) 45%, var(--line)); background:color-mix(in srgb, var(--danger) 5%, var(--paper)); }
.retgroup.today { border-color:color-mix(in srgb, var(--warn) 45%, var(--line)); background:color-mix(in srgb, var(--warn) 5%, var(--paper)); }
.rethead { font-size:11px; letter-spacing:.16em; text-transform:uppercase; font-weight:700; padding:11px 14px 3px; color:var(--ink-soft); }
.retgroup.late .rethead { color:var(--danger); }
.retgroup.today .rethead { color:var(--warn); }
.retrow { display:flex; align-items:center; gap:12px; padding:11px 14px; text-decoration:none; color:var(--ink);
  border-top:1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.retrow:first-of-type { border-top:none; }
.retmain { flex:1; min-width:0; }
.retclient { font-size:15px; font-weight:500; }
.retsub { font-size:12px; color:var(--ink-faint); margin-top:3px; }
.retwhen { flex:none; display:flex; flex-direction:column; align-items:flex-end; line-height:1.05; text-align:right; }
.retdays { font-family:var(--serif); font-size:19px; font-weight:700; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
.retlbl { font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint); margin-top:3px; }
.retgroup.late .retdays, .retgroup.late .retlbl { color:var(--danger); }
.retgroup.today .retlbl { color:var(--warn); font-weight:700; font-size:13px; letter-spacing:.06em; }

.rform .slabel { margin-top:24px; }
.fld { width:100%; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:13px 14px; font-family:var(--sans); font-size:15px; color:var(--ink); background:var(--field); outline:none; margin-bottom:9px; }
.fld:focus { border-color:var(--ink); }
.daterow { display:flex; gap:10px; }
.daterow .datefld, .pedirwhen .datefld { min-width:0; }
.daterow .datefld input, .pedirwhen .datefld input { min-width:0; width:100%; }
.datefld { flex:1; display:flex; flex-direction:column; gap:5px; }
.datefld span { font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint); }
.datefld input { border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 13px; font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--field); outline:none;
  /* iOS Safari sizes a native-appearance date input to its intrinsic pill width,
     ignoring flex constraints — two side-by-side fields merged and ran offscreen
     (s27, the rede piece page). appearance:none lets width rules win; min-height
     covers the WebKit quirk where an EMPTY appearance-less date input collapses. */
  -webkit-appearance:none; appearance:none; min-height:47px; }
.datefld input:focus { border-color:var(--ink); }
.picklist { display:flex; flex-direction:column; border:1px solid var(--line); border-radius:var(--r-ctl); overflow:hidden; }
.pickrow { display:flex; align-items:center; gap:12px; padding:10px 12px; border-bottom:1px solid var(--line); cursor:pointer; }
.pickrow:last-child { border-bottom:none; }
.pickrow:has(input[type=checkbox]:checked) { background:var(--paper-2); }
.pickrow > input[type=checkbox] { width:20px; height:20px; flex:none; accent-color:var(--accent); }
.pickimg { width:38px; height:48px; flex:none; border-radius:4px; border:1px solid var(--line); overflow:hidden; display:grid; place-items:center; background:var(--paper); }
.pickimg img { width:100%; height:100%; object-fit:cover; }
.pickimg svg { width:50%; height:50%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.5; }
.pickname { flex:1; min-width:0; font-size:14px; display:flex; flex-direction:column; gap:2px; }
.picksub { font-size:11.5px; color:var(--ink-faint); }
.pickprice { width:74px; flex:none; border:1px solid var(--line-2); border-radius:7px; padding:9px 10px; font-size:13px; color:var(--ink); background:var(--paper); outline:none; text-align:right; }
.pickprice:focus { border-color:var(--ink); }
/* mechanical label (idiom 12): the price came from the category table, not the ficha */
.cathint { font-size:11px; color:var(--muted); }

/* the digital wall list (s25): one quiet row per category, saved on change */
.catprice-row { display:flex; align-items:center; gap:10px; padding:7px 0; border-bottom:1px solid var(--line); }
.catprice-row:last-of-type { border-bottom:none; }
.catprice-nm { flex:1; min-width:0; font-size:13.5px; color:var(--ink); }
.catprice-in { flex:none; width:110px; }
.catprice-in .fld { text-align:right; }

/* the romaneio's QUANT column (s25) — narrow, quiet, defaults to 1 */
.pickqty { width:40px; flex:none; border:1px solid var(--line-2); border-radius:7px; padding:9px 6px; font-size:13px; color:var(--muted); background:var(--paper); outline:none; text-align:center; }
.pickqty:focus { border-color:var(--ink); color:var(--ink); }
.rform .save { margin-top:22px; }

.rilist { display:flex; flex-direction:column; gap:2px; }
/* VENDIDAS (s84): the valor sits right, a number to read at a glance down the column */
.vendlist .vendprice { flex:none; font-size:14px; font-weight:600; color:var(--ink); }
.pedpub-items .pedpub-price { flex:none; font-size:14px; font-weight:600; color:var(--ink); }
.rilook-head { display:flex; align-items:center; gap:6px; font-size:11px; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--accent);
  padding:14px 2px 5px; text-decoration:none; }
.rilook-head svg { width:14px; height:14px; stroke:currentColor; stroke-width:1.6;
  fill:none; stroke-linecap:round; stroke-linejoin:round; opacity:.75; }
/* the door hints it's a door (s39): document glyph in the accent dot, faint chevron */
.rilook-head svg:not(.chev) { stroke:var(--dot); opacity:1; }
.rilook-head .chev { width:12px; height:12px; stroke:var(--ink-faint); margin-left:-3px; }
.rilook-head:first-child { padding-top:2px; }
/* One row = the piece (anchor) + its editable line price (form) — a form can't nest
   inside an anchor, so the row splits them. */
.rirow { display:flex; align-items:center; gap:10px; border-bottom:1px solid var(--line); }
.rirow:last-child { border-bottom:none; }
.rirow .riitem { flex:1; min-width:0; border-bottom:none; }
.riitem { display:flex; align-items:center; gap:12px; padding:9px 2px; text-decoration:none; color:var(--ink); border-bottom:1px solid var(--line); }
.riitem:last-child { border-bottom:none; }
.riprice { margin-left:auto; font-size:13px; color:var(--ink-soft); flex:none; }
/* rede attribution on a borrowed line (s38): globe + acervo name, quiet accent. */
.riowner { display:inline-flex; align-items:center; gap:4px; font-size:11px; color:var(--accent); margin-left:6px; vertical-align:-1px; }
.riowner svg { width:12px; height:12px; stroke:currentColor; stroke-width:1.6; fill:none; }
/* The ledger row's mini-pile (s42+): up to 3 overlapped piece thumbs, same row height
   as the old single .pickimg — the row shows the actual pieces, not just a count. */
.pile { display:flex; align-items:center; flex:none; height:48px; }
.pile .pchip { width:34px; height:44px; flex:none; border-radius:4px; border:1px solid var(--line);
  overflow:hidden; margin-left:-11px; background:var(--paper); display:grid; place-items:center;
  box-shadow:-3px 0 6px -3px var(--shadow); }
.pile .pchip:first-child { margin-left:0; }
.pile .pchip img { width:100%; height:100%; object-fit:cover; }
.pile .pchip.empty svg { width:50%; height:50%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.5; }
/* State as a pre-attentive dot + label — read the pending/confirmed axis down the
   column at a glance, not by decoding an uppercase pill. */
.statecap { display:inline-flex; align-items:center; gap:6px; flex:none; font-size:11px;
  color:var(--ink-soft); white-space:nowrap; }
.sdot { width:8px; height:8px; border-radius:50%; flex:none; background:var(--ink-faint); }
.sdot.st-confirmed { background:var(--accent); }
.sdot.st-picked_up { background:var(--ok); }
.sdot.st-returned { background:var(--ink-soft); }
.sdot.st-draft { background:var(--ink-faint); }
.sdot.st-closed, .sdot.st-cancelled { background:var(--line-2); }
/* Long produtora names no longer break the row rhythm. */
.pickname .nm { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* the line-price quiet edit (s39): the Pago row's own .qmoney dialect — faint R$
   as TEXT (never the form's beige .rsym box), a narrow right-aligned .qedit that
   rests transparent. 16px blocks iOS focus-zoom (idiom 1). */
.riprice-form { flex:none; display:flex; align-items:baseline; gap:4px; }
.ri-rsym { font-size:12px; color:var(--ink-faint); }
/* .riprice-form scope out-specifies the LATER .qedit base (source order bit the
   old 64px rule — the base's width:calc(100%+14px) always won) */
.riprice-form .riprice-in { display:inline-block; width:72px; margin:0; padding:4px 6px; text-align:right; font-size:16px; }
/* the denominator, said once on the eyebrow: line prices are flat pelo período */
.mesasec-lbl .ri-period { margin-left:auto; font-size:11px; font-weight:400;
  letter-spacing:.02em; text-transform:none; color:var(--ink-faint); }
/* Contato + channel, one row (s38): waicon · number · the state verb. The number is
   reference data — the tap is the payload, so the balloon+verb lead, the number recedes. */
.riwa { display:flex; align-items:center; gap:10px; margin:2px 0 10px; }
.riwa-num { font-size:13px; color:var(--ink-soft); }
.riwa-verb { font-size:11.5px; color:var(--ink-faint); margin-left:auto; }

/* rascunho BUILD header (s39, Option B): the detail page IS the edit surface for a
   draft — client name = editable title, job = subtitle, período/caução inline (idiom 1),
   no separate edit page, no Save button (autosave), one commit verb below. */
.tt .qtitle-form, .tt .qjob-form { position:relative; }
.qtitle { font-family:var(--serif); font-weight:700; font-size:28px; letter-spacing:-.03em;
  line-height:1.05; color:var(--ink); }
.qtitle::placeholder { color:var(--ink-faint); }
.qjob { font-size:14px; color:var(--ink-soft); margin-top:2px; }
.qjob::placeholder { color:var(--ink-faint); }
.datefld form { display:contents; }   /* the autosave wrapper is invisible layout */
.rcaucao.qmoney { display:inline-flex; flex:none; align-items:baseline; gap:5px; margin-top:4px; }
.rcaucao .qmoney-r { font-size:15px; color:var(--ink-faint); }
.rcaucao.qmoney .qedit { width:90px; text-align:left; font-size:16px; }
/* RECORD mood's quiet date facts (s39): borderless native date inputs that read as
   text in a .row until tapped — never the build form's white boxes. */
.rpq { display:inline-flex; align-items:center; gap:2px; justify-content:flex-end; }
.rpq form { display:contents; }
.rpq .qdate { display:inline-block; width:104px; margin:0; padding:2px 0; font-size:15px;
  text-align:right; -webkit-appearance:none; appearance:none; background:none; }
.rpq .qdate::-webkit-calendar-picker-indicator { display:none; }
.rpsep { color:var(--ink-faint); font-size:14px; }
/* inline quantity on a draft line: × prefix + narrow field, sits before the price */
.riqty-form { flex:none; display:flex; align-items:baseline; gap:2px; }
.ri-mult { font-size:12px; color:var(--ink-faint); }
.riqty-form .riqty-in { display:inline-block; width:34px; margin:0; padding:4px; text-align:center; font-size:16px; }
/* nova locação CHECKOUT rows (s39): the .picklist card, verb-less — no checkbox
   column. Right side = the EDITABLE price (step 2: pricing is born here) over its
   quiet hint — seed math for her own piece, cost warning for a rede piece. */
.rnewlist { margin-top:2px; }
.rnewrow { cursor:default; }
.pickprice-col { flex:none; margin-left:auto; display:flex; flex-direction:column; align-items:flex-end; gap:3px; max-width:46%; }
.rnewprice { display:flex; align-items:baseline; gap:4px; }
.rnewprice-in { width:76px; border:1px solid var(--line-2); border-radius:8px; padding:6px 8px;
  text-align:right; font-size:16px; font-family:var(--sans); color:var(--ink);
  background:var(--field); outline:none; font-variant-numeric:tabular-nums; }
.rnewprice-in:focus { border-color:var(--accent); }
.pickmath { font-size:11.5px; color:var(--ink-soft); text-align:right; line-height:1.35; }
/* the line's availability warning (s39): quiet amber fact, never a block */
.pickbusy { font-size:11.5px; color:var(--warn); text-align:right; }
/* pick-mode's ocupadas tail (s39): available first, the booked sink into one honest
   disclosure — count in the summary (idiom 14), volta date on each tile, still pickable */
.pickbusy-tail { margin-top:16px; }
.pickbusy-tail > summary { list-style:none; cursor:pointer; display:flex; align-items:center;
  gap:5px; font-size:12.5px; color:var(--ink-soft); padding:6px 2px; }
.pickbusy-tail > summary::-webkit-details-marker { display:none; }
.pickbusy-tail > summary svg { width:13px; height:13px; stroke:currentColor; stroke-width:1.8;
  fill:none; stroke-linecap:round; transition:transform .18s ease; }
.pickbusy-tail[open] > summary svg { transform:rotate(90deg); }
.pickbusy-tail .grid { margin-top:8px; }
.pickbusy-tail .tile { opacity:.72; }
.pickvolta { display:block; margin-top:3px; font-size:11px; color:var(--warn); text-align:center; }
/* the contract landing's quiet secondary verbs (s39): Confirmar-sem-assinatura +
   Baixar share one demoted row under the primary send */
.pdfquiet { display:flex; gap:8px; margin-top:8px; }
.pdfquiet form { flex:1; min-width:0; display:flex; }
.pdfquiet .quiet2 { flex:1; min-width:0; padding:11px 8px; font-size:13px; color:var(--ink-soft); }

.conflict-box { margin-top:18px; border:1px solid var(--accent); border-radius:var(--r-ctl); padding:13px 15px; font-size:13px; color:var(--accent); line-height:1.5; }
.conflict-box.warn { border-color:var(--line-2); color:var(--ink-soft); background:var(--paper-2); }
.conflict-box strong { display:block; margin-bottom:6px; font-size:13px; }
.conflict-box ul { margin:0 0 6px; padding-left:18px; }
.conflict-box li { margin:2px 0; }
.cb-foot { font-size:12px; opacity:.85; }
.ractions { display:flex; flex-direction:column; gap:10px; margin-top:4px; }
.ractions form { margin:0; }
.btn.primary { background:var(--accent); color:var(--on-accent); border-color:var(--accent); }
.btn.primary:active { background:var(--accent-press); }
/* input + verb on one line. A flex item's min-width defaults to AUTO, so the input
   refused to shrink below an <input>'s intrinsic ~20-character width and pushed the
   non-shrinking button off the right edge ("Registrar pagamen…" clipped on a 390pt
   phone). min-width:0 lets it give way; wrap is the backstop for the narrowest
   screens + biggest type — the verb drops to its own line instead of leaving. */
.closeform { display:flex; flex-wrap:wrap; gap:9px; }
.closeform input { flex:1 1 8.5rem; min-width:0; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:13px 14px; font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--field); outline:none; }
.closeform .btn { width:auto; flex:0 1 auto; min-width:0; }
.avail-out { display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:var(--accent); margin-top:8px; }
.avail-out .dot { width:7px; height:7px; border-radius:50%; background:var(--accent); }
/* Rede state line (s11 swap) — a quiet, tappable status beside Disponível; it stopped
   dressing as a button (it's set ~once per piece; read rarely). Tap → the same sheet. */
/* s49 — THE REDE GLOBE in the ficha's top bar: state + verb in one glyph. */
.redeglobe-form { display:contents; }
.redeglobe { width:36px; height:36px; border-radius:50%; border:1.5px solid var(--line-2); background:none; padding:0;
  display:grid; place-items:center; cursor:pointer; color:var(--ink-faint); -webkit-appearance:none; appearance:none;
  -webkit-tap-highlight-color:transparent; transition:transform .12s; }
.redeglobe svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
.redeglobe .strike { display:none; }
.redeglobe.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.redeglobe.off .strike { display:block; }
.redeglobe.blocked { border-style:dashed; opacity:.75; }
.redeglobe:active { transform:scale(.92); }
.redehint { display:flex; align-items:center; gap:8px; margin-top:10px; font-size:12.5px; color:var(--warn); }
.redehint svg { width:15px; height:15px; flex:none; fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; }
/* The rede 'falta polir' third state (s80): a ✦ action, not the globe — plum, inviting. */
.redeglobe.polish { background:var(--tint); border-color:transparent; color:var(--accent); }
.redeglobe.polish svg { fill:currentColor; stroke:none; width:18px; height:18px; }
button.redehint { border:0; background:none; font:inherit; padding:0; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.redehint-polish { color:var(--accent); }
.redehint-polish svg { fill:currentColor; stroke:none; }
.redehint-polish b { font-weight:600; }
.menusheet-note { margin:0; padding:4px 12px 12px; font-size:13.5px; line-height:1.45; color:var(--ink-soft); }
/* the toast (s49): one dark line above the nav, confirms a flip and offers desfazer */
.toast { position:fixed; left:50%; bottom:calc(114px + env(safe-area-inset-bottom)); z-index:70; display:flex; align-items:center; gap:12px; white-space:nowrap;
  max-width:calc(100% - 36px); padding:9px 10px 9px 16px; border-radius:999px; background:var(--ink); color:var(--paper); font-size:13.5px;
  box-shadow:0 6px 24px rgba(0,0,0,.18); opacity:0; transform:translate(-50%, 8px); transition:opacity .2s, transform .2s; }
.toast.on { opacity:1; transform:translate(-50%, 0); }
.toast svg { width:16px; height:16px; flex:none; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; opacity:.85; }
.toast-undo { border:1px solid color-mix(in srgb, currentColor 34%, transparent); background:none; padding:5px 13px; color:var(--paper); font-family:inherit; font-size:13px; font-weight:500;
  border-radius:999px; cursor:pointer; }
/* content layout inside the promoted mesalink (kept class names from the old row) */
.rederow-body { flex:1; display:flex; flex-direction:column; gap:1px; min-width:0; }
.rederow-body b { font-size:14px; font-weight:600; color:var(--ink); }
.rederow-body small { font-size:12px; color:var(--ink-faint); }
.rederow-chev { width:18px; height:18px; fill:none; stroke:var(--ink-faint); stroke-width:2; flex:none;
  stroke-linecap:round; stroke-linejoin:round; }
.badge.overdue { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }
.btn.contract { display:flex; align-items:center; justify-content:center; gap:9px; text-decoration:none; }
.btn.contract svg { width:17px; height:17px; stroke:var(--accent); stroke-width:1.5; fill:none; stroke-linecap:round; stroke-linejoin:round; }

.rrow .chev { width:20px; height:20px; flex:none; stroke:var(--ink-faint); stroke-width:1.6; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.rrow.static { cursor:default; }
select.fld { appearance:none; -webkit-appearance:none; background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 10l5 5 5-5' fill='none' stroke='%236F6657' stroke-width='1.6' stroke-linecap='round'/></svg>"); background-repeat:no-repeat; background-position:right 13px center; }
textarea.fld { resize:vertical; line-height:1.5; }
.addrow { display:flex; gap:9px; margin-top:14px; }
/* min-width:0 lets the input shrink below its intrinsic placeholder width — without it a
   flex item refuses to shrink (min-width:auto), the row overflows, and iOS expands the
   layout viewport so the whole page reads as zoomed out (s22 device fix). */
.addrow input { flex:1; min-width:0; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:13px 14px; font-family:var(--sans); font-size:14.5px; color:var(--ink); background:var(--field); outline:none; }
.addrow input:focus { border-color:var(--ink); }
.addrow button { flex:none; border:none; background:var(--ink); color:var(--paper); border-radius:var(--r-ctl); padding:0 18px; font-family:var(--sans); font-size:13px; font-weight:500; cursor:pointer; }

.statusrow { display:flex; gap:8px; margin-top:12px; }
.statusrow form { margin:0; }
.schip { font-size:12.5px; color:var(--ink-soft); border:1px solid var(--line-2); border-radius:2px; padding:7px 14px; background:var(--paper); cursor:pointer; font-family:var(--sans); }
.schip.on { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }

/* Cenas (s21) — the scene spine. Chips toggle which scenes a look (troca) spans;
   the project list rows open the scene view; the cast-card strip is the mobile
   costume plot (filled cell = dressed, hollow = the gap). */
.scnpick { display:flex; align-items:baseline; gap:10px; margin-top:12px; }
.scnpick-lbl { flex:none; font-size:11px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); }
.scnpick-chips { display:flex; flex-wrap:wrap; gap:7px; }
.scnchip { position:relative; font-size:12.5px; font-family:var(--sans); color:var(--ink-soft); border:1px solid var(--line-2); border-radius:2px; padding:6px 11px; background:var(--paper); cursor:pointer; user-select:none; }
.scnchip input { position:absolute; opacity:0; pointer-events:none; }
.scnchip.on { color:var(--on-accent); background:var(--accent); border-color:var(--accent); }
.scnlist { margin-top:10px; display:flex; flex-direction:column; }
.scnrow { display:flex; align-items:center; border-bottom:1px solid var(--hair); }
.scnrow-go { flex:1; display:flex; align-items:baseline; gap:10px; padding:12px 2px; text-decoration:none; color:var(--ink); min-width:0; }
.scnnum { flex:none; font-size:14px; }
.scnlabel { flex:1; font-size:13.5px; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.scncount { flex:none; font-size:12px; color:var(--ink-faint); }
/* Figuração signals on the scene row (s22): the crowd ALERT (needs a decision) vs the
   count once she's set it. */
.scn-fig-alert { flex:none; font-size:10.5px; font-weight:600; color:var(--chip-warn-ink); background:var(--chip-warn-bg); border-radius:2px; padding:2px 7px; }
.scn-fig { flex:none; font-size:10.5px; color:var(--ink-soft); background:var(--paper-2); border-radius:2px; padding:2px 7px; }
.scnx { margin:0; }
.scnx button { border:none; background:none; color:var(--ink-faint); font-size:18px; line-height:1; padding:10px 6px; cursor:pointer; }
.scnadd .scnadd-num { flex:0 0 64px; }
.npdoor { margin-bottom:6px; }
.npdrop { display:flex; align-items:center; gap:14px; padding:18px 16px; border:1.5px dashed var(--line-2); border-radius:12px; cursor:pointer; margin-top:6px; }
.npdrop svg { flex:none; width:30px; height:30px; fill:none; stroke:var(--accent); stroke-width:1.6; }
.npdrop b { display:block; font-size:15px; color:var(--ink); }
.npdrop small { display:block; margin-top:3px; font-size:12.5px; color:var(--ink-soft); line-height:1.4; }
.npmanual { margin-top:14px; }
.scncast { margin-top:10px; display:flex; flex-direction:column; }
.scncast-row { display:flex; align-items:baseline; gap:12px; padding:12px 2px; border-bottom:1px solid var(--hair); }
.scncast-name { flex:none; min-width:96px; font-size:14.5px; color:var(--ink); text-decoration:none; }
.scncast-looks { flex:1; display:flex; flex-wrap:wrap; gap:7px; }
.scncast-look { font-size:12.5px; color:var(--accent); border:1px solid color-mix(in srgb, var(--accent) 45%, transparent); border-radius:2px; padding:5px 10px; text-decoration:none; }
.scncast-look.ok { color:var(--chip-ok-ink); background:var(--chip-ok-bg); border-color:transparent; }
.scncast-none { font-size:12.5px; color:var(--ink-faint); text-decoration:none; }

/* Scene blocks (s22 arc): each character-in-scene as a scoped card — identity + the
   troca(s) worn here, each with a peças↔render toggle. */
.scnblocks { display:flex; flex-direction:column; gap:12px; margin-top:12px; }
.scnblock { border:1px solid var(--line); border-radius:12px; background:var(--card); padding:13px 14px; }
.scnblock-tap { cursor:pointer; }
.scnblock-head { display:flex; align-items:center; gap:11px; }
/* rule 9: the ripening face — render → foto → initial */
/* actor faces are SQUARES with rounded corners everywhere in the pipeline (s23b:
   charface 14px @104 → 10px @44); circles are for the USER avatar + controls only */
.scnface { flex:none; width:44px; height:44px; border-radius:10px; overflow:hidden;
  background:var(--card2, var(--paper-2)); color:var(--accent); font-weight:800; font-size:17px;
  display:grid; place-items:center; }
.scnface img { width:100%; height:100%; object-fit:cover; }
.scnblock-id { display:flex; flex-direction:column; gap:2px; min-width:0; }
/* continuity note chip + form (events revision: user-entered, AI only offers) */
/* CONTINUA (persistence-first): connecting an existing look beats creating a new one */
.scncontinua { margin-top:9px; }
.scncontinua button { font:inherit; font-size:13px; text-align:left; width:100%;
  color:var(--accent); background:none; border:1px dashed var(--line-2); border-radius:10px;
  padding:9px 11px; cursor:pointer; }
.scncontinua b { font-weight:700; }
.scnnote { display:block; margin-top:9px; font:inherit; font-size:12.5px; text-align:left;
  color:var(--ink-faint); background:none; border:none; padding:2px 0; cursor:pointer; }
.scnnote.offer { color:var(--warn, #b0762e); font-weight:600; }
.scnnote.has { color:var(--ink-soft); font-weight:600; }
.scnnote-form { display:flex; gap:7px; margin-top:7px; }
.scnnote-form[hidden] { display:none; }
.scnnote-form input { flex:1; font:inherit; font-size:13.5px; padding:8px 10px;
  border:1px solid var(--line-2); border-radius:10px; background:var(--paper-2); color:var(--ink); }
.scnnote-form button { font:inherit; font-size:13px; font-weight:700; padding:8px 13px;
  border-radius:10px; border:1px solid var(--accent); background:none; color:var(--accent); }
.scnblock-name { font-size:15.5px; font-weight:600; color:var(--ink); text-decoration:none; letter-spacing:-.01em; }
.scnblock-desc { font-size:12.5px; color:var(--ink-soft); }
.scnblock-none { display:inline-block; margin-top:9px; font-size:12.5px; color:var(--ink-faint); text-decoration:none; }
.scnlook { margin-top:11px; }
.scnlook-top { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.scnlook-label { font-size:13.5px; color:var(--ink); text-decoration:none; }
.scnlook-ok { font-size:10px; color:var(--chip-ok-ink); background:var(--chip-ok-bg); border-radius:2px; padding:1px 6px; vertical-align:1px; }
.scnlook-tabs { flex:none; display:flex; gap:3px; padding:3px; background:var(--paper-2); border-radius:var(--r-ctl); }
.scnlook-tab { border:none; background:none; border-radius:6px; padding:4px 11px; font-family:var(--sans); font-size:11.5px; color:var(--ink-soft); cursor:pointer; }
.scnlook-tab.on { background:var(--card); color:var(--ink); box-shadow:0 1px 2px rgba(0,0,0,.08); }
.scnlook-view { margin-top:10px; }
.scnlook-view[hidden] { display:none; }
.scnlook-pecas { display:flex; flex-wrap:wrap; gap:7px; }
.scnlook-peca { width:56px; height:75px; border-radius:7px; overflow:hidden; border:1px solid var(--line); background:var(--paper-2); display:block; }
.scnlook-peca img { width:100%; height:100%; object-fit:cover; display:block; }
.scnlook-peca svg { width:100%; height:100%; fill:none; stroke:var(--line-2); stroke-width:1.4; padding:14px; box-sizing:border-box; }
.scnlook-render { width:100%; max-width:220px; border-radius:var(--r-ctl); display:block; }
.scnlook-montar { display:inline-block; font-size:12.5px; color:var(--accent); text-decoration:none; }

/* Decupagem (s21) — the intake block + the A3b confirm draft. */
.decu textarea { width:100%; margin-top:10px; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 14px; font-family:var(--sans); font-size:14.5px; color:var(--ink); background:var(--paper); outline:none; resize:vertical; }
.decu-file input { font-size:13px; color:var(--ink-soft); margin-top:10px; }
.decu-go { display:block; width:100%; margin-top:12px; border:none; background:var(--ink); color:var(--paper); border-radius:var(--r-ctl); padding:13px; font-family:var(--sans); font-size:14px; font-weight:500; cursor:pointer; }
.decu-go:disabled { opacity:.55; cursor:default; }
.decu-note { margin-top:8px; }
.decu-head { margin-top:10px; font-size:13px; color:var(--ink-soft); }
.decu-sec { margin-top:16px; font-size:11px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); }
.decu-row { display:flex; gap:10px; align-items:baseline; padding:9px 2px; border-bottom:1px solid var(--hair); cursor:pointer; }
.decu-row input { flex:none; accent-color:var(--accent); }
.decu-body { flex:1; font-size:14px; color:var(--ink); }
.decu-bio { display:block; font-size:12.5px; color:var(--ink-soft); }
.decu-tag { font-size:10.5px; color:var(--accent); border:1px solid color-mix(in srgb, var(--accent) 45%, transparent); border-radius:2px; padding:1px 6px; margin-left:6px; }
.decu-cancel { display:block; text-align:center; margin-top:10px; font-size:13px; color:var(--ink-faint); }
.decu-warn { margin-top:10px; padding:10px 12px; border-radius:var(--r-ctl); background:var(--chip-warn-bg); color:var(--chip-warn-ink); font-size:13px; line-height:1.45; }
.decu-autotag { font-size:10.5px; color:var(--chip-warn-ink); background:var(--chip-warn-bg); border-radius:2px; padding:1px 6px; margin-left:6px; }
.decu-cite { display:block; margin-top:5px; font-size:12px; font-style:italic; line-height:1.45; color:var(--ink-soft); border-left:2px solid color-mix(in srgb, var(--accent) 45%, transparent); padding-left:9px; }
.decu-cite.bad { font-style:normal; color:var(--chip-warn-ink); border-left-color:var(--chip-warn-ink); }
.decu-reason { font-size:10.5px; color:var(--ink-soft); background:var(--paper-2); border-radius:2px; padding:1px 6px; margin-left:6px; }
.decu-cancelbtn { border:none; background:none; width:100%; cursor:pointer; font-family:var(--sans); }
/* The background-extraction progress panel (s22 hardening): while a job is live this
   panel IS the block — no button exists to re-trigger. */
.decu-progress { margin-top:12px; padding:13px 15px; border:1px solid var(--line); border-radius:10px; background:var(--card); font-size:14px; color:var(--ink); }
.decu-progress .btnspin { margin-right:6px; }
.decu-progress .decu-note { margin-top:8px; }
.decu-titlerow { background:color-mix(in srgb, var(--accent) 8%, transparent); border-radius:var(--r-ctl); padding:9px 10px; border-bottom:none; margin-top:10px; }
.npscript input { font-size:13px; color:var(--ink-soft); }
.npopt { font-size:10.5px; letter-spacing:0; text-transform:none; color:var(--accent); }

/* The roteiro, kept (s22) — the persisted script card + the verbatim /cena excerpt. */
.roteiro-card { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:14px; padding:11px 13px; background:var(--card); border:1px solid var(--line); border-radius:var(--r-ctl); }
.roteiro-name { display:flex; align-items:center; gap:8px; font-size:13.5px; color:var(--ink); min-width:0; }
.roteiro-name svg { flex:none; width:17px; height:17px; fill:none; stroke:var(--accent); stroke-width:1.7; }
.roteiro-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.roteiro-actions { flex:none; display:flex; align-items:center; gap:14px; }
.roteiro-view { font-size:13px; color:var(--accent); text-decoration:none; }
.roteiro-del { border:none; background:none; padding:0; font-family:var(--sans); font-size:13px; color:var(--ink-faint); cursor:pointer; }
.cena-src { margin-top:22px; }
.cena-src > summary { font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); cursor:pointer; }
.cena-text { margin-top:12px; padding:14px 15px; background:var(--card); border:1px solid var(--line); border-radius:var(--r-ctl); font-family:var(--sans); font-size:13.5px; line-height:1.6; color:var(--ink); white-space:pre-wrap; overflow-wrap:break-word; }

/* The project money glance (s22) — consumido vs verba, the one alarm after previsto died. */
.money-glance { margin:2px 0 16px; padding:11px 15px; border:1px solid var(--line); border-radius:12px; background:var(--card); font-size:14px; color:var(--ink); font-variant-numeric:tabular-nums; }
.money-glance .money-of { color:var(--ink-faint); }
.money-glance.over { color:var(--danger); border-color:color-mix(in srgb, var(--danger) 40%, var(--line)); }
.money-glance.over .money-of { color:color-mix(in srgb, var(--danger) 70%, var(--ink-faint)); }
/* Inline edit — quiet-until-tapped (docs/ui-language.md idiom 1): the editable
   fields ARE the permanent display. Resting = a plain fact (transparent border, no
   box); :focus reveals the affordance (hairline + card wash) in place. The negative
   margin cancels the padding so resting text sits flush with the layout. Inputs stay
   ≥16px so iOS never focus-zooms. */
.qedit { display:block; width:calc(100% + 14px); margin-left:-7px; padding:3px 7px;
  border:1px solid transparent; border-radius:var(--r-ctl); background:transparent;
  font-family:var(--sans); font-size:16px; line-height:1.4; color:var(--ink);
  -webkit-appearance:none; appearance:none; resize:none; outline:none; overflow:hidden; }
.qedit:focus { border-color:var(--line-2); background:var(--card); }
.qedit::placeholder { color:var(--ink-faint); }

/* Produção dashboard header (s23): identity reads first — title, episode subheader,
   meta chips, money glance; every fact edited where it's displayed. */
.projhead { margin:20px 0 8px; position:relative; }
.projsaved { position:absolute; top:2px; right:0; font-size:12px; color:var(--ok, #4c7a5a);
  opacity:0; transition:opacity .25s; pointer-events:none; }
.projsaved.on { opacity:1; }
.qtitle-form { position:relative; }
.qtitle-form .inline-saved { position:absolute; top:-2px; right:0; margin:0; }
.projtitle-q { font-size:26px; font-weight:800; letter-spacing:-.01em; line-height:1.15; }
.qsub { font-size:16px; color:var(--ink-faint); letter-spacing:.02em; margin-top:2px; }
/* per-fact tiny form (ficha rows): inline in the .v slot, value right-aligned like
   every row value; its ✓ salvo floats just above the row's right edge. */
.qfield { display:inline-flex; align-items:baseline; gap:4px; position:relative; flex:1; min-width:0; }
.qfield .inline-saved { position:absolute; top:-15px; right:0; margin:0; white-space:nowrap; }
.qfield .qedit { width:100%; margin:0; padding:2px 6px; text-align:right; }
.qfield .qmoney-r { flex:none; font-size:15px; color:var(--ink-faint); }
.qmoney .qedit { width:110px; flex:none; }
/* Money in a meta row is a VALUE, so it right-aligns with its siblings — 900 lines up
   under 1.500 — and the R$ sits against the number instead of stranded to its left. */
.row .qmoney { gap:5px; }
.row .qmoney .qedit { width:88px; text-align:right; }   /* fits R$ 99.999 at 16px */
/* Derived money on a meta row: 'em aberto' is what she owes you, so it carries weight;
   'quitado' recedes because a settled balance needs no attention. */
.row .v.open { color:var(--accent); font-weight:600; }
.row .v.quit { color:var(--ink-faint); font-weight:400; }
/* Buscar disabled = a promise, not a dead control: visibly grey, non-tappable,
   flipping to accent the instant words exist (typed or dictated). */
.briefsheet-go:disabled { background:var(--paper-2); color:var(--ink-faint);
  cursor:default; pointer-events:none; }
/* the query's visible home (v1.0) — editable while a search is active */
.qhome { display:flex; align-items:center; gap:9px; border:1px solid var(--line-2);
  border-radius:999px; padding:9px 6px 9px 15px; background:var(--paper); margin:14px 0 12px; }   /* s72: breathe below the masthead */
.qhome svg { width:17px; height:17px; stroke:var(--ink-faint); stroke-width:1.7; fill:none;
  stroke-linecap:round; flex:none; }
.qhome input { flex:1; min-width:0; border:none; background:none; font-family:var(--sans);
  font-size:16px; color:var(--ink); outline:none; }
.qhome-x { flex:none; width:32px; height:32px; display:grid; place-items:center;
  border-radius:50%; color:var(--ink-faint); text-decoration:none; }
/* s74: an SVG × (grid-centered) — the text glyph's own metrics sat it high in the circle. */
.qhome-x svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.8; fill:none; stroke-linecap:round; }
.qhome-x:active { background:var(--paper-2); }
/* the dead screen, fixed: real exits + the rede band */
/* s74 (his call): the search zero-state sits between the filters and the rede band, so its
   top gap should match the button→gallery gap below it (padding-bottom 10 + band margin 26),
   not the roomy 72px a full-page empty state wants. */
.emptysearch { padding-top:36px; padding-bottom:10px; }
.emptyfilters { font-size:12.5px; color:var(--ink-faint); margin-top:8px; }
.emptyacts { display:flex; flex-wrap:wrap; gap:9px; justify-content:center; margin-top:16px; }
.emptyacts .btn { width:auto; flex:0 1 auto; padding:12px 18px; }
/* THE REDE STRIP (s49 re-dress): a deeper ground + the section eyebrow, so the change of
   place — mine above, theirs below — is visible from across the room; #redehits is the
   pointer's landing. */
.redeband { margin:26px -8px 0; padding:14px 8px 12px; background:var(--paper-2); border-radius:var(--r-card);
  scroll-margin-top:14px; }
.redeband-l { display:flex; align-items:center; gap:8px; margin:0 2px 12px; }
.redeband-l.redesec { margin:0 2px 12px; }
.redeband-l svg { width:16px; height:16px; stroke:var(--accent); stroke-width:1.7; fill:none; flex:none; }
.redejump { color:var(--accent); text-decoration:none; }
.redejump .mesasec-n { color:var(--accent); }
.redejump-arrow { font-size:12px; margin-left:1px; }
.redetile .sb { color:var(--accent); }
/* the bench chip on the acervo stat line — status + verb in one element */
.ovstat-mesa { border:none; background:none; padding:0; font-family:var(--sans);
  font-size:inherit; color:var(--accent); font-weight:600; cursor:pointer; }
/* the clear verb flows inside the .ovstat text line; explicit [hidden] guard because
   an author display rule silently defeats the hidden attribute (the zero-pin state) */
.ovstat-mesaform { display:inline; }
.ovstat-mesaform[hidden] { display:none; }
/* on the acervo the mesa-clear verb rides the FAR RIGHT of the Peças eyebrow as a
   pin-with-✕ icon (Option C) — a row-action, unnamed; hidden ⇒ display:none */
.pinclearform { margin-left:auto; display:inline-flex; align-items:center; }
/* generous hit area (~40px) — he was frustrated by tiny clear targets; the glyph stays
   small, the tappable padding does the Fitts work, negatives keep the row compact */
.pinclear { display:inline-flex; align-items:center; justify-content:center; border:none;
  background:none; cursor:pointer; padding:11px; margin:-11px -6px -11px 0; color:var(--ink-soft); }
.pinclear-glyph { position:relative; display:inline-flex; }
.pinclear-glyph svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; }
.pinclear-x { position:absolute; right:-4px; top:-4px; font-size:10px; line-height:1;
  font-weight:800; color:var(--accent); }
.optsheet form { margin:0; }
button.optrow { width:100%; border:none; background:none; text-align:left;
  font-family:var(--sans); cursor:pointer; }
.redefold { margin-top:22px; }
.redefold > summary { list-style:none; display:flex; align-items:center; gap:8px; cursor:pointer;
  padding:10px 2px; font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-faint); border-top:0.5px solid var(--line); }
.redefold > summary::-webkit-details-marker { display:none; }
.redefold > summary svg { width:15px; height:15px; stroke:var(--ink-faint); stroke-width:1.6; fill:none; flex:none; }
.redefold > summary .chev { margin-left:auto; stroke-width:1.8; transition:transform .18s; }
.redefold[open] > summary .chev { transform:rotate(90deg); }
.redefold .redeband { margin-top:6px; }
/* Phase D: rede pieces on the bench */
.tomesa.show .tomesa-pin { opacity:1; filter:drop-shadow(0 1px 2.5px rgba(20,16,10,.3)); }
.tomesa.show .tomesa-pin circle { fill:var(--paper); stroke:var(--line-2); }
.tomesa.show .tomesa-pin path { stroke:var(--ink-soft); }
.tilewrap.on-mesa .tomesa.show .tomesa-pin circle { fill:var(--paper); stroke:var(--line-2); }
.tilewrap.on-mesa .tomesa.show .tomesa-pin path { stroke:var(--accent); }
.slotnet { position:absolute; right:6px; top:6px; z-index:3; width:20px; height:20px; border-radius:50%;
  background:var(--paper); display:grid; place-items:center; box-shadow:0 1px 4px var(--shadow); }
.slotnet svg { width:12px; height:12px; stroke:var(--accent); stroke-width:1.7; fill:none; }
.si-owner { display:block; font-size:11.5px; color:var(--accent); }
.si-owner:empty { display:none; }
.netowner { color:var(--accent); }
.reelnet { right:5px; top:5px; }
/* ONE STATE, ONE VERB (v1.0) — the rental page's shape */
.nextstep { margin-top:4px; }
.nextstep .btn.primary { width:100%; }
.nextnote { margin-top:9px; }
.nextnote summary { list-style:none; font-size:13px; color:var(--ink-faint); cursor:pointer; padding:4px 2px; }
.nextnote summary::-webkit-details-marker { display:none; }
.nextnote[open] summary { color:var(--ink-soft); }
.nextnote input { width:100%; margin-top:7px; border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:12px 14px; font-family:var(--sans); font-size:16px; color:var(--ink);
  background:var(--paper); outline:none; }
.nextnote input:focus { border-color:var(--ink); }
/* destructive corner: quiet text, off the main path */
.rdanger { display:flex; gap:18px; justify-content:center; margin:30px 0 4px; }
.rdanger button { border:none; background:none; font-family:var(--sans); font-size:13px;
  color:var(--ink-faint); cursor:pointer; padding:8px 4px; }
.rdanger button:active { color:var(--danger); }
/* cobrança: the WhatsApp button already IS the loudest thing on the page (brand
   green, white text) — the LABEL carries the change of meaning, not a recolour.
   Tinting it accent-on-green made the text unreadable. */
.wabtn.cobrar { font-weight:600; }
.paidall { display:flex; justify-content:flex-end; margin-top:-2px; }
.paidall button { border:none; background:none; font-family:var(--sans); font-size:12.5px;
  color:var(--accent); cursor:pointer; padding:6px 2px; }
/* despesas drawer: closed by default, count + total stay visible (idiom 14) */
.expdrawer > summary { list-style:none; display:flex; align-items:center; gap:10px;
  cursor:pointer; padding:6px 2px; font-size:11px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-faint); }
.expdrawer > summary::-webkit-details-marker { display:none; }
.expdrawer > summary b { margin-left:auto; font-size:14px; letter-spacing:0;
  text-transform:none; color:var(--ink); font-weight:600; }
.expdrawer > summary svg { width:16px; height:16px; stroke:var(--ink-faint); stroke-width:1.8;
  fill:none; transition:transform .18s; flex:none; }
.expdrawer[open] > summary svg { transform:rotate(90deg); }
.contractblock { display:flex; flex-direction:column; gap:10px; }
.btn.contract.quiet { font-weight:400; }
/* assinatura (v1.0): the photographed-paper signature — Perfil block + rental door */
.sigblock { margin-top:16px; display:flex; flex-direction:column; gap:8px; }
.sigblock [hidden] { display:none; }   /* in-place toggle (s35i): [hidden] must win over flex-child display */
.sigpreview { border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--card);
  padding:10px 14px; display:flex; justify-content:center; }
.sigpreview img { max-height:64px; max-width:100%; }
[data-theme="dark"] .sigpreview { background:#ECE4DB; }  /* ink previews on paper, both themes */
.sigacts { display:flex; gap:9px; align-items:center; }
.sigremove { border:none; background:none; font-family:var(--sans); font-size:13px;
  color:var(--ink-faint); cursor:pointer; padding:8px 4px; }
.sigdoor { position:relative; }
.sigerr { font-size:12.5px; color:var(--danger); margin:2px 0 6px; }
.sighint { font-size:12.5px; color:var(--ink-faint); margin:8px 2px 0; }
.sighint a { color:var(--accent); }
.sigchip { display:inline-flex; align-items:center; gap:7px; font-size:13px; color:var(--ok);
  margin:0 0 10px; font-weight:500; }
.sigchip svg { width:15px; height:15px; stroke:currentColor; stroke-width:2; fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* R$ prefix inside a closeform (idiom 11: money never renders as a naked number) */
.closeform-r { align-self:center; font-size:15px; color:var(--ink-faint); flex:none; margin-right:-4px; }
.row .v.vq { display:flex; flex:1; justify-content:flex-end; align-items:baseline; gap:4px; min-width:0; }
.row .v .qfield { justify-content:flex-end; }
.fichaname-q { font-family:var(--serif); font-weight:700; font-size:28px; letter-spacing:-.03em; line-height:1.1; }
.qnotesform { display:block; flex:none; }
.qnotesform .qedit { text-align:left; width:calc(100% + 12px); margin-left:-6px; font-size:16px; color:var(--ink-soft); line-height:1.55; }
.projep { display:block; color:var(--accent); font-weight:700; font-size:15px; margin-top:5px;
  background:none; border:none; padding:0; font-family:inherit; cursor:pointer; text-align:left; }
.projep.ghost { color:var(--ink-faint); font-weight:600; }
.projep[hidden] { display:none; }
.projchips { display:flex; flex-wrap:nowrap; gap:5px; align-items:center; margin-top:16px; }
.pchip { flex:none; font-size:12px; font-weight:600; border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:5px 10px; color:var(--ink); background:none; font-family:inherit; cursor:pointer;
  white-space:nowrap; }
.pchip:active { background:var(--paper-2); }
.pchip.ghost { color:var(--ink-faint); border-style:dashed; font-weight:500; }
.pchip-sel { -webkit-appearance:none; appearance:none; }
/* Only the client name may shrink+ellipsis so the three chips never wrap — Série and
   the date chip stay full (flex:none above); Dead Pet Filmes fits untruncated. */
#fClient { flex:0 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; }
/* 'limpar datas' drops to its own full-width line below the two date fields,
   right-aligned — the date inputs keep their flex:1 width. */
.projrow-clear { flex:0 0 100%; text-align:right; margin-top:2px; font:inherit; font-size:12px;
  color:var(--danger); background:none; border:none; padding:2px 2px; cursor:pointer; }
.projrow-clear[hidden] { display:none; }
.projfieldrow { margin-top:8px; }
.projfieldrow[hidden] { display:none; }
.projfieldrow input[type=text] { width:100%; box-sizing:border-box; font:inherit; font-size:14px;
  background:var(--card); border:1px solid var(--line-2); border-radius:10px; padding:9px 11px;
  color:inherit; }
.projdaterow { display:flex; flex-wrap:wrap; gap:8px; }
.projdaterow label { flex:1; display:flex; flex-direction:column; gap:3px; font-size:10.5px;
  font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-faint); }
.projdaterow input { font:inherit; font-size:14px; background:var(--card);
  border:1px solid var(--line-2); border-radius:10px; padding:8px 10px; color:inherit; }
.projeprow { display:flex; gap:8px; margin-top:6px; }
.projeprow[hidden] { display:none; }
.projeprow input { font:inherit; font-size:14px; background:var(--card);
  border:1px solid var(--line-2); border-radius:10px; padding:8px 10px; color:inherit; }
.projeprow input:first-child { flex:0 0 26%; }
.projeprow input:last-child { flex:1; }
.projhead .money-glance { margin:14px 0 0; display:flex; align-items:center; flex-wrap:wrap; gap:2px; }
.mg-verba { font:inherit; font-size:14px; color:inherit; background:none; border:none; padding:0;
  cursor:pointer; font-variant-numeric:tabular-nums; }
.mg-verba.ghost { color:var(--ink-faint); }
.mg-verba[hidden] { display:none; }
.mg-verbain { display:inline-flex; align-items:center; gap:5px; }
.mg-verbain[hidden] { display:none; }
.mg-verbain input { width:110px; font:inherit; font-size:14px; background:var(--card);
  border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:5px 8px; color:inherit; }
.mg-spent { font-variant-numeric:tabular-nums; }
.lookadopt { margin-top:8px; }
.lookadopt select { font:inherit; font-size:13px; color:var(--accent); background:var(--card);
  border:1px dashed var(--line-2); border-radius:999px; padding:6px 12px;
  -webkit-appearance:none; appearance:none; }
/* The arrival strip: what the pour created + live avisos. Accent-tinted, transient. */
.pourstrip { position:relative; margin:14px 0 4px; padding:12px 13px; border-radius:14px;
  border:1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  background:color-mix(in srgb, var(--accent) 9%, var(--card)); }
.pourstrip[hidden] { display:none; }
.pourstrip-x { position:absolute; top:8px; right:10px; border:none; background:none;
  color:var(--ink-faint); font-size:16px; cursor:pointer; padding:2px 6px; }
.pourstrip-lbl { font-size:10.5px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--accent); }
.pourstrip-big { font-size:14px; font-weight:700; margin-top:4px; }
.pourstrip-warns { margin-top:7px; }
.pourstrip-warns summary { font-size:13px; font-weight:600; color:var(--warn, #b0762e);
  cursor:pointer; list-style:none; }
.pourstrip-warns summary::-webkit-details-marker { display:none; }
.pourstrip-warns ul { margin:8px 0 2px; padding-left:4px; list-style:none;
  display:flex; flex-direction:column; gap:6px; }
.pourstrip-warns a { color:var(--ink); font-size:13px; text-decoration:underline;
  text-decoration-color:var(--line-2); }
.projnotes textarea { width:100%; box-sizing:border-box; }

/* The cast roster (s22) — 2-per-row tappable faces; tap drills into the character card. */
.castroster { display:grid; grid-template-columns:repeat(2, 1fr); gap:13px; margin:6px 0 16px; }
.casttile { display:flex; flex-direction:column; text-decoration:none; color:inherit; border:1px solid var(--line); border-radius:14px; overflow:hidden; background:var(--card); }
.casttile:active { border-color:var(--accent); }
.castface { position:relative; aspect-ratio:1; background:var(--paper-2); display:block; }
.castface img { width:100%; height:100%; object-fit:cover; display:block; }
.castface-initial { position:absolute; inset:0; display:grid; place-items:center; font-family:var(--serif); font-size:52px; font-weight:700; color:var(--ink-faint); }
.casttile-name { font-size:15px; font-weight:600; letter-spacing:-.01em; margin:10px 12px 0; }
.casttile-actor { font-size:12px; color:var(--ink-faint); margin:1px 12px 0; }
.casttile-cov { font-size:11.5px; color:var(--ink-faint); margin:3px 12px 12px; display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.casttile-warn { font-size:10.5px; color:var(--chip-warn-ink); background:var(--chip-warn-bg); border-radius:2px; padding:2px 7px; }

/* The character card (s22) — the depth the roster face defers to. */
.charhero { display:flex; gap:15px; align-items:flex-start; margin:6px 0 16px; }
.charface-wrap { position:relative; flex:none; }
/* The face IS the 'foto de perfil' opener: tap → the crop editor. An empty box overlays a
   real transparent file input (opacity:0, NOT hidden) so the iOS picker anchors to the tap. */
.charface { position:relative; display:block; width:104px; height:104px; border:none; padding:0; border-radius:14px; overflow:hidden; background:var(--paper-2); cursor:pointer; }
.charface img { width:100%; height:100%; object-fit:cover; display:block; }
.charface-initial { width:100%; height:100%; display:grid; place-items:center; font-family:var(--serif); font-size:44px; font-weight:700; color:var(--ink-faint); }
.charface input[type=file] { position:absolute; inset:0; opacity:0; cursor:pointer; }
/* the character crop guide is a rounded square (the face box), not the avatar's circle */
.charavedit .avedit-ring::after { border-radius:16px; }
.charhead { min-width:0; flex:1; }
.charhead h1 { font-family:var(--serif); font-size:26px; font-weight:600; margin:2px 0 0; letter-spacing:-.01em; }
.charbio { font-size:14px; color:var(--ink-soft); line-height:1.5; margin:6px 0 0; }
/* MESA DE REFERÊNCIA (s24): the template board — a dense magazine grid the app lays
   out (destaque = 2×2). Tiles are buttons (tap → item sheet); the dashed + is the door. */
/* FIXED row tracks, no aspect-ratio: WebKit sizes grid rows from the item's content,
   not its aspect-ratio height — tiles painted ~2× their row and overlapped on iOS
   (the device mosaic bug). Fixed tracks are deterministic on every engine; tiles
   stretch to their track and the absolute img cover-fills. */
.refboard { display:grid; grid-template-columns:repeat(3, 1fr); gap:6px;
  grid-auto-rows:140px; grid-auto-flow:dense; margin:8px 0 18px; }
.rbtile { position:relative; border:none; padding:0; background:var(--paper-2);
  border-radius:10px; overflow:hidden; cursor:pointer; }
.rbtile img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.rbtile.big { grid-column:span 2; grid-row:span 2; }
.rbtile.rbadd { display:grid; place-items:center; background:none;
  border:1.5px dashed var(--line-2); color:var(--ink-faint); font-size:26px; }
.rbtile-name { display:grid; place-items:center; width:100%; height:100%; padding:8px;
  font-size:12px; color:var(--ink-faint); text-align:center; }
.rbsheet-panel { display:flex; flex-direction:column; gap:8px; max-height:82vh; overflow-y:auto; }
.rbdoors { display:flex; flex-direction:column; gap:8px; }
/* an author display beats the hidden attribute — guard the sheet's toggled panes
   (the device bug: the doors stayed visible under the open picker) */
.rbdoors[hidden], .rbpick[hidden] { display:none; }
.rbpick-filter { width:100%; font:inherit; font-size:16px; padding:9px 12px;
  border:1px solid var(--line-2); border-radius:10px; background:var(--paper);
  color:var(--ink); outline:none; margin-bottom:8px; }
.rbpick-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:6px;
  grid-auto-rows:150px; max-height:46vh; overflow-y:auto; }
.rbpick-tile { position:relative; border-radius:10px; overflow:hidden; background:var(--paper-2);
  cursor:pointer; display:block; }
.rbpick-tile[hidden] { display:none; }
.rbpick-tile img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.rbpick-tile input { position:absolute; top:6px; left:6px; width:20px; height:20px;
  accent-color:var(--accent); z-index:2; }
.rbpick-noimg { display:grid; place-items:center; width:100%; height:100%;
  font-size:24px; color:var(--ink-faint); }
.rbpick-name { position:absolute; left:0; right:0; bottom:0; font-size:10.5px;
  padding:3px 6px; background:color-mix(in srgb, var(--paper) 82%, transparent);
  color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rbpick-tile:has(input:checked) { outline:2.5px solid var(--accent); outline-offset:-2.5px; }
.rbpick-go { margin-top:10px; }
.rbitem-name { font-family:var(--serif); font-size:16px; font-weight:600; padding:2px 2px 4px; }
.rbitem-avail { font-size:12.5px; color:var(--ok); padding:0 2px 8px; }
.rbitem-avail.na_rua { color:var(--danger); }
.rbitem-avail.reservada { color:var(--warn); }
.rbitem-avail[hidden] { display:none; }
.rbitem-rm span b { color:var(--danger); }

/* The card's identity editor (quiet-until-tapped): name reads as the h1, bio as the
   muted paragraph — both are the live fields. The shared "✓ salvo" floats top-right. */
.charedit-q { position:relative; }
.charedit-q .inline-saved { position:absolute; top:-2px; right:0; margin:0; }
.charedit-q .qname { font-family:var(--serif); font-size:26px; font-weight:600; letter-spacing:-.01em; line-height:1.2; margin-top:2px; }
.charedit-q .qactor { font-size:16px; font-weight:600; color:var(--accent); margin-top:1px; }
.measurefld select.medsel { font:inherit; font-size:16px; background:var(--card);
  border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:7px 9px; color:var(--ink);
  min-width:104px; }
.charedit-q .qbio { font-size:16px; color:var(--ink-soft); line-height:1.45; margin-top:2px; }
/* Part 1 of the bio: the script's own introduction, verbatim. Reads as a QUOTE (it is
   one) and is deliberately not an input — frozen text carrying its own receipt. */
.charintro { font-size:14px; line-height:1.5; color:var(--ink-soft); font-style:italic;
  margin-top:6px; }
.introproof { background:none; border:none; padding:0 0 0 5px; cursor:pointer;
  color:var(--accent); vertical-align:-2px; }
.introproof svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.chargal { display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
.chargal form { margin:0; }
.charthumb { position:relative; width:60px; height:60px; border-radius:var(--r-ctl); overflow:hidden; border:1px solid var(--line); }
.charthumb img { width:100%; height:100%; object-fit:cover; display:block; cursor:pointer; }
.charthumb button { position:absolute; top:0; right:0; width:19px; height:19px; padding:0; border:none; border-radius:0 0 0 7px; background:rgba(15,12,9,.6); color:#fff; font-size:13px; line-height:1; cursor:pointer; }
.charadd { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; width:60px; height:60px; border-radius:var(--r-ctl); border:1px dashed var(--line-2); background:var(--paper-2); color:var(--ink-faint); cursor:pointer; }
.charadd input[type=file] { position:absolute; width:1px; height:1px; opacity:0; }
.charadd svg { width:18px; height:18px; stroke:var(--ink-faint); stroke-width:1.6; fill:none; }
.charadd span { font-size:9px; }
.chartrocas { display:flex; flex-direction:column; gap:9px; }
.chartroca { display:block; text-decoration:none; color:inherit; padding:11px 13px; border:1px solid var(--line); border-radius:10px; background:var(--card); }
.chartroca-head { display:block; font-size:14px; color:var(--ink); }
.chartroca-scn { color:var(--ink-faint); font-weight:400; font-size:12.5px; }
.chartroca .decu-cite { margin-top:6px; }
.charscenes { display:flex; flex-direction:column; }
.charscene { padding:13px 2px; border-bottom:1px solid var(--hair); }
.charscene-top { display:flex; align-items:baseline; gap:12px; justify-content:space-between; }
.charscene-num { font-size:14px; color:var(--ink); text-decoration:none; }
.charscene-looks { display:flex; flex-wrap:wrap; gap:7px; justify-content:flex-end; }
.charscene .cena-src { margin-top:9px; }
.charcons { font-variant-numeric:tabular-nums; }
.charcons-tot { font-family:var(--serif); font-size:24px; font-weight:600; color:var(--ink); }
.charexp { margin-top:11px; display:flex; flex-direction:column; }
.charexp-row { display:flex; align-items:baseline; justify-content:space-between; gap:12px; padding:9px 2px; border-bottom:1px solid var(--hair); font-size:13.5px; }
.charexp-what { color:var(--ink); }
.charexp-when { color:var(--ink-faint); font-size:12px; }
.charexp-val { color:var(--ink); }

/* Script revisions (s22, Phase 4) — the new-version door, the diff, and the change flag. */
.roteiro-ver { font-size:11px; color:var(--ink-faint); font-weight:400; }
.roteiro-newver { margin-top:9px; }
.roteiro-newver-file { display:block; position:relative; text-align:center; font-size:13px; color:var(--accent); border:1px dashed var(--line-2); border-radius:var(--r-ctl); padding:11px; cursor:pointer; }
.roteiro-newver-file input[type=file] { position:absolute; inset:0; opacity:0; cursor:pointer; }
.rev { margin-top:12px; }
.rev-summary { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:12px; }
.rev-pill { font-size:11.5px; font-weight:600; border-radius:2px; padding:3px 9px; }
.rev-pill.ch { color:var(--chip-warn-ink); background:var(--chip-warn-bg); }
.rev-pill.add { color:var(--chip-ok-ink); background:var(--chip-ok-bg); }
.rev-pill.rem { color:var(--chip-alert-ink); background:var(--chip-alert-bg); }
.rev-scene { border:1px solid var(--line); border-radius:var(--r-ctl); margin-bottom:8px; overflow:hidden; }
.rev-scene > summary { padding:10px 13px; font-size:13.5px; color:var(--ink); cursor:pointer; }
.rev-diff { margin:0; padding:11px 13px; border-top:1px solid var(--line); background:var(--card); font-family:var(--sans); font-size:12.5px; line-height:1.5; color:var(--ink); white-space:pre-wrap; overflow-wrap:break-word; }
.rev-diff .rev-add { display:block; color:var(--chip-ok-ink); background:color-mix(in srgb, var(--ok) 10%, transparent); }
.rev-diff .rev-del { display:block; color:var(--chip-alert-ink); background:color-mix(in srgb, var(--danger) 10%, transparent); }
.rev-diff .rev-ctx { display:block; color:var(--ink-soft); }
.rev-removed { font-size:12.5px; color:var(--ink-soft); line-height:1.5; margin:6px 0 12px; }
.rev-flag { font-size:10.5px; font-weight:600; color:var(--chip-warn-ink); background:var(--chip-warn-bg); border-radius:2px; padding:1px 6px; }
.rev-banner { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:14px; padding:11px 13px; border-radius:var(--r-ctl); background:var(--chip-warn-bg); font-size:13px; line-height:1.4; color:var(--ink); }
.rev-banner button { flex:none; border:none; background:none; font-family:var(--sans); font-size:12.5px; font-weight:600; color:var(--chip-warn-ink); cursor:pointer; text-decoration:underline; }

/* Long-call wait: the inline button spinner (decupagem & friends). */
.btnspin { display:inline-block; width:13px; height:13px; vertical-align:-2px; margin-right:2px;
  border:2px solid color-mix(in srgb, currentColor 30%, transparent); border-top-color:currentColor;
  border-radius:50%; animation:btnspin .8s linear infinite; }
@keyframes btnspin { to { transform:rotate(360deg); } }

/* The roteiro viewer (in-app PDF pages). */
.rotpages { display:flex; flex-direction:column; gap:10px; margin-top:14px; }
.rotpage { width:100%; height:auto; display:block; border:1px solid var(--line); border-radius:var(--r-ctl); background:#fff; }

/* Organizar toggle (s22) — the produção's two projections (Personagens · Cenas) as one
   segmented control; prep vs shoot, her choice persists, phase-derived default. */
.orgtoggle { display:flex; gap:4px; margin:26px 0 16px; padding:4px; background:var(--paper-2); border-radius:11px; }
.orgseg { flex:1; border:none; background:none; border-radius:var(--r-ctl); padding:9px 6px; font-family:var(--sans); font-size:13px; font-weight:500; color:var(--ink-soft); cursor:pointer; letter-spacing:.01em; }
.orgseg.on { background:var(--card); color:var(--ink); box-shadow:0 1px 2px rgba(0,0,0,.08); }
.orgview[hidden] { display:none; }

/* Arc B — the Mesa search scope (só o meu · a rede toda) + the rede tier. */
.netscope { display:flex; gap:8px; margin-top:12px; }
/* scope pills wear the purple-pill idiom (the filter chips' family) — the museum 2px is gone */
.nspill { font-size:13px; font-family:var(--sans); color:var(--accent); border:1px solid var(--accent);
  border-radius:20px; padding:8px 14px; background:var(--tint); text-decoration:none; }
.nspill.on { color:var(--on-accent); background:var(--accent); border-color:var(--accent); font-weight:600; }
.tierlabel { margin:16px 0 10px; font-size:11px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); }
/* a tier that came back empty inside a search is ONE quiet line, not a 72px void */
.empty.empty--tier { padding:6px 0 16px; }
.empty.empty--tier p { font-size:13px; }
.netowner { color:var(--accent); }
.netflip { display:inline-block; margin-top:10px; font-size:14px; color:var(--accent); text-decoration:none; }
/* Per-piece ASKING state (s44): quiet "a pedir" (still to ask), accent "pedida" (asked →
   it's a pedido in Trabalhos now), amber "a enviar" during the send confirm. In the caption
   under the image, never on it. */
.pcst-pedir { color:var(--ink-faint); }
.pcst-pedida { color:var(--accent); font-weight:600; }
.pcst-enviar { color:var(--warn); font-weight:600; }
.pcst-ok { color:var(--chip-ok-ink); font-weight:600; }
/* Stacked caption (s44): size · owner · status each on their OWN line, so nothing wraps
   mid-phrase and a long acervo name gets a full line (ellipsis if truly huge). */
.sbstack { display:flex; flex-direction:column; gap:0; line-height:1.32; }
.sbstack .sbl { display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Send preview: the pieces about to go get an amber ring; the rest dim so the subset is
   unmistakable (the confirm carries only the count/owner/dates — the images say WHICH). */
.bcard.a-enviar .tile .img { box-shadow:0 0 0 2.5px var(--warn); }
#lookPieces.previewing .bcard:not(.a-enviar) { opacity:.4; transition:opacity .15s; }
.board .bcard { position:relative; }
/* Ghost: a look piece that left (trashed/sold/off-rede) — greyed in place, with the reason,
   dropped from the pedido; the same language the look's composed card uses (s80). */
.bcard.is-ghost .tile .img { filter:grayscale(1); opacity:.62; }
.bcard.is-ghost .sbl { color:var(--ink-faint); }
.bghost-lbl { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); z-index:3;
  font-size:9.5px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; white-space:nowrap;
  color:var(--paper); background:rgba(20,16,10,.8); border-radius:999px; padding:3px 8px; }
/* 'gerando' placeholder (AJAX Provar/Refazer): a spinner card that a finished render
   replaces in place — no reload, so the carousel keeps its chosen pieces. */
.bcard.gen .tile { pointer-events:none; }
.bcard.gen .genspin { width:26px; height:26px; border-radius:50%;
  border:2.5px solid color-mix(in srgb, var(--accent) 25%, transparent); border-top-color:var(--accent);
  animation:sparkspin .9s linear infinite; }
.bcard.gen .sb { color:var(--ink-soft); }
.bcard.gen.err .genspin { display:none; }
@keyframes sparkspin { to { transform:rotate(360deg); } }   /* the board's gerando spinner (the ficha ✦ no longer spins — s72) */
.bcard.gen.err .sb { color:var(--warn); }
/* long-press delete on the generated-image cards (shared hold-ring). */
.bcard.holding .hold-ring { display:flex; }
.bcard .bx { position:absolute; top:6px; right:6px; margin:0; }
.bcard .bx button { width:26px; height:26px; border-radius:50%; border:none; background:rgba(26,24,20,.62); color:#fff; font-size:16px; line-height:1; cursor:pointer; display:grid; place-items:center; }
/* The delete-× is an SVG (two crossed lines) — symmetric, so it sits DEAD-CENTER in the
   circle (a text × renders optically high). Any .bx button holding an svg gets sized here. */
.bx button svg { width:12px; height:12px; stroke:currentColor; stroke-width:2.4; fill:none; stroke-linecap:round; display:block; }
.addpieces { margin-top:18px; }
.addrow-form { margin:0; cursor:default; }
.addbtn { flex:none; width:34px; height:34px; border-radius:50%; border:1px solid var(--accent); background:var(--paper); color:var(--accent); font-size:20px; line-height:1; cursor:pointer; display:grid; place-items:center; }
.addbtn:active { background:var(--accent); color:var(--on-accent); }
.lookadd select { flex:none; max-width:42%; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:0 12px; font-family:var(--sans); font-size:13px; color:var(--ink); background:var(--field); }

/* M5 — presentations (owner dashboard) */
.sharebox { margin-top:22px; border:1px solid var(--line-2); border-radius:10px; padding:16px; background:var(--paper-2); }
.sharebox.revoked { opacity:.72; }
.sharebox .slabel { margin:0 0 10px; }
.shareurl { width:100%; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:11px 13px; font-family:var(--sans); font-size:13px; color:var(--ink-soft); background:var(--paper); outline:none; }
.sharebtns { display:flex; gap:9px; margin-top:11px; align-items:stretch; }
.sharebtns .btn, .sharebtns form { width:auto; flex:1; margin:0; }
.sharebtns .btn { display:flex; align-items:center; justify-content:center; }
.btn.ghost { color:var(--ink-soft); }
.btn.ghost:active { border-color:var(--ink); }
.prlook { border-bottom:1px solid var(--line); padding:4px 0 14px; }
.prlook .rrow { border-bottom:none; }
.rthumb { width:46px; height:58px; flex:none; border-radius:5px; overflow:hidden; border:1px solid var(--line); display:grid; place-items:center; background:var(--paper-2); }
.rthumb img { width:100%; height:100%; object-fit:cover; }
.rthumb svg { width:46%; height:46%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.55; }
.schip.status-approved { background:var(--ok); border-color:var(--ok); color:var(--on-accent); }
.schip.status-rejected { background:var(--danger); border-color:var(--danger); color:var(--on-accent); }
.schip.status-pending { background:var(--paper); border-color:var(--line-2); color:var(--ink-soft); }
.decided { font-size:11.5px; color:var(--ink-faint); margin:2px 2px 0 60px; font-style:italic; }
.thread { margin:10px 2px 0 60px; display:flex; flex-direction:column; gap:8px; }
.cmt { border-left:2px solid var(--line-2); padding:2px 0 2px 11px; }
.cmt.owner { border-left-color:var(--accent); }
.cmeta { font-size:11px; color:var(--ink-faint); letter-spacing:.02em; }
.cbody { font-size:13.5px; color:var(--ink); line-height:1.5; margin-top:2px; }
.prremove { margin:11px 2px 0 60px; }
.linkbtn { background:none; border:none; padding:0; font-family:var(--sans); font-size:12px; color:var(--ink-faint); cursor:pointer; letter-spacing:.02em; }
.linkbtn:active { color:var(--accent); }

/* M5 — client approval surface (public /v/[token]) */
.cv { max-width:560px; margin:0 auto; padding:0 18px 80px; min-height:100vh; background:var(--paper); }
.cv-head { padding:46px 0 26px; text-align:center; border-bottom:1px solid var(--line); }
.cv-brand { font-family:var(--serif); font-size:13px; letter-spacing:.34em; color:var(--accent); text-transform:uppercase; }
.cv-head h1 { font-family:var(--serif); font-weight:500; font-size:27px; line-height:1.15; margin:14px 0 0; }
.cv-hint { font-size:13.5px; color:var(--ink-faint); margin:10px auto 0; max-width:340px; line-height:1.5; }
.cv-name { width:100%; max-width:300px; margin:20px auto 0; display:block; border:1px solid var(--line-2); border-radius:999px; padding:11px 18px; text-align:center; font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--paper); outline:none; }
.cv-name:focus { border-color:var(--ink); }
.cv-look { padding:34px 0; border-bottom:1px solid var(--line); transition:background .4s ease; }
.cv-look.status-approved { background:linear-gradient(var(--paper), color-mix(in srgb, var(--ok) 7%, var(--paper))); }
.cv-look.status-rejected { background:linear-gradient(var(--paper), color-mix(in srgb, var(--danger) 7%, var(--paper))); }
.cv-label { text-align:center; margin-bottom:20px; }
.cv-char { font-size:11px; letter-spacing:.22em; text-transform:uppercase; color:var(--ink-faint); }
.cv-label h2 { font-family:var(--serif); font-weight:500; font-size:21px; margin-top:5px; }
.cv-photos { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.cv-photos.solo { grid-template-columns:1fr; }
.cv-photo { margin:0; }
.cv-photo img { width:100%; aspect-ratio:2/3; object-fit:cover; border-radius:var(--r-ctl); border:1px solid var(--line); display:block; }
.cv-noimg { aspect-ratio:2/3; border-radius:var(--r-ctl); border:1px solid var(--line); display:grid; place-items:center; background:var(--paper-2); }
.cv-noimg svg { width:38%; height:38%; stroke:var(--ink-soft); stroke-width:1; fill:none; opacity:.5; }
.cv-photo figcaption { font-size:12px; color:var(--ink-faint); margin-top:7px; text-align:center; }
.cv-decision { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:22px; }
.cv-state { font-size:12px; letter-spacing:.04em; color:var(--ink-faint); }
.cv-state-approved { color:var(--ok); font-weight:500; }
.cv-state-rejected { color:var(--danger); font-weight:500; }
.cv-btns { display:flex; gap:9px; }
.cv-form { margin:0; }
.cv-btn { border:1px solid var(--line-2); background:var(--paper); color:var(--ink); border-radius:999px; padding:11px 22px; font-family:var(--sans); font-size:14px; font-weight:500; cursor:pointer; transition:all .18s; }
.cv-btn.approve.on { background:var(--ok); border-color:var(--ok); color:var(--on-accent); }
.cv-btn.reject.on { background:var(--danger); border-color:var(--danger); color:var(--on-accent); }
.cv-btn:active { transform:scale(.97); }
.cv-thread { margin-top:20px; display:flex; flex-direction:column; gap:9px; }
.cv-cmt { font-size:13.5px; line-height:1.5; }
.cv-cmt-who { font-weight:500; color:var(--ink); margin-right:7px; }
.cv-cmt-body { color:var(--ink-soft); }
.cv-commentform { display:flex; flex-wrap:wrap; gap:9px; margin-top:18px; }
.cv-commentform input { flex:1 1 8rem; min-width:0; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 14px; font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--field); outline:none; }
.cv-commentform input:focus { border-color:var(--ink); }
.cv-commentform button { flex:none; border:none; background:var(--ink); color:var(--paper); border-radius:var(--r-ctl); padding:0 18px; font-family:var(--sans); font-size:13px; font-weight:500; cursor:pointer; }
.cv-foot { text-align:center; padding:34px 0 0; font-family:var(--serif); font-size:12px; letter-spacing:.3em; color:var(--ink-faint); text-transform:uppercase; }

/* M5.1 — piece edit */
.editlink { font-size:13px; color:var(--accent); text-decoration:none; letter-spacing:.02em; }
.editlink:active { color:var(--accent-press); }
.editphotos { display:flex; gap:8px; overflow-x:auto; padding:4px 0 2px; margin-bottom:6px; }
.editphoto { flex:none; width:60px; height:76px; border-radius:6px; overflow:hidden; border:1px solid var(--line); }
.editphoto img { width:100%; height:100%; object-fit:cover; }

/* M5.2 — financials (/money) */
.topactions { display:flex; align-items:center; gap:14px; }
.stats { display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-top:8px; }
.stat { border:1px solid var(--line); border-radius:10px; padding:15px 12px; text-align:center; background:var(--paper); }
.snum { font-family:var(--serif); font-size:18px; font-weight:500; letter-spacing:.01em; line-height:1.1; }
.snum.ok { color:var(--ok); }
.snum.warn { color:var(--warn); }
.slbl { font-size:10.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-faint); margin-top:7px; }
.statnote { font-size:12px; color:var(--ink-faint); margin:11px 2px 4px; }
.rmoney { flex:none; text-align:right; }
.rbal { font-size:15px; font-weight:500; font-variant-numeric:tabular-nums; }
.rpaid { font-size:11.5px; color:var(--ink-faint); margin-top:2px; }
.row.col { flex-direction:column; align-items:flex-start; gap:5px; }
.row.col .v.note { text-align:left; font-size:14px; color:var(--ink-soft); line-height:1.5; }

/* M-tryon — AI try-on (look renders) */
.tryonform { margin-top:8px; display:flex; flex-direction:column; gap:9px; }
.tryonform textarea { border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 14px; font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--paper); outline:none; resize:vertical; }
.tryonform textarea:focus { border-color:var(--ink); }
.tryonform button[type="submit"] { align-self:flex-start; border:1px solid var(--accent); background:var(--accent); color:var(--on-accent); border-radius:var(--r-ctl); padding:11px 20px; font-family:var(--sans); font-size:13.5px; font-weight:500; cursor:pointer; }
.tryonform button[type="submit"]:disabled { opacity:.6; cursor:default; }
.tryonhint { font-size:12.5px; margin-top:9px; }
/* tap-a-thumbnail cover picker (#16 follow-up) — thumbs are buttons now; the
   original photo(s) + AI catalog renders sit side by side, tap to set the cover */
.thumbs form, .thumbs .thumbadd-wrap { display:contents; }
button.thumb { position:relative; padding:0; background:var(--paper-2); cursor:pointer;
  font:inherit; -webkit-appearance:none; appearance:none; }
/* reorder-drag: horizontal moves are the drag (captured); vertical still scrolls the page */
button.thumb[data-pid], button.thumb[data-catid] { touch-action:pan-y; }
.thumb.dragging { opacity:.55; transform:scale(1.06); box-shadow:0 4px 14px rgba(20,16,10,.28); transition:none; }
/* Photo-actions sheet — tap a strip photo for cover / polish / IA / delete */
.pash[hidden] { display:none; }
.pash { position:fixed; inset:0; z-index:96; display:flex; align-items:flex-end; }
.pash-backdrop { position:absolute; inset:0; background:rgba(20,16,10,.42); }
.pash-panel { position:relative; width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:20px 20px 0 0; padding:16px 12px calc(16px + env(safe-area-inset-bottom)); box-shadow:0 -8px 30px rgba(0,0,0,.22); }
/* s76 (his call): the limpeza help closes with a corner × instead of a full-width Fechar
   button — the button ate breathing room on the card. */
.pash-x { position:absolute; top:8px; right:8px; width:34px; height:34px; border:none; background:none;
  font-size:24px; line-height:1; color:var(--ink-faint); cursor:pointer; display:grid; place-items:center; z-index:3; }
.pash-preview { display:flex; gap:12px; justify-content:center; margin-bottom:8px; }
.pash-preview figure { margin:0; text-align:center; }
.pash-preview img { width:88px; aspect-ratio:2/3; object-fit:cover; border-radius:6px; display:block; }
.pash-preview figcaption { font-size:11px; color:var(--ink-faint); margin-top:4px; letter-spacing:.03em; }
.pash-status { font-size:12.5px; color:var(--ink-soft); text-align:center; margin:6px 0 2px; }
.pash-status.err { color:var(--brick); }
/* s74 — the inline polish panel: opens under the hero, above the thumbnails, as a card on
   the page (not a floating sheet). No scrim, no thumbnail — the hero above is the piece. */
.polishpanel { margin:12px 0 2px; padding:14px 14px 16px; background:var(--card);
  border:1px solid var(--line); border-radius:14px; }
.polishpanel[hidden] { display:none; }
/* s77 (his call): the ficha polish dropdown — Cancelar sits the same 14px from the card's
   bottom as from its sides (base .polishpanel bakes 16px); and the card's gap to the photo
   strip matches the strip's gap to the 'na mesa' pin below it (22px, via margin collapse). */
#polishsheet { padding-bottom:14px; margin-bottom:22px; }
/* Catalog-style chips in the ✨ sheet (s33): single-select, the chosen one is the
   sticky default. Three equal pills; the selected wears the accent. */
.pash-styles { display:flex; gap:8px; margin:0 0 6px; }
/* the caption under the chips (s50): follows the chosen chip, says the sticky rule once,
   and carries the door to the examples — the samples are never a permanent row */
.pash-styles { margin-bottom:10px; }
/* The honest disclaimer (s72): inline before the first spend, and inside the '?' sheet.
   text-wrap:pretty keeps a single word off its own last line; the nbsp in the copy guards
   the older engines that lack it. */
.stylenote, .styleex-note { margin:0 0 12px; font-size:12px; line-height:1.5; color:var(--ink-soft);
  text-align:center; text-wrap:balance; }
.stylenote[hidden] { display:none; }
.styleex-note { margin:0 0 4px; }
.stylehelp { flex:none; width:34px; padding:0; border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper);
  color:var(--ink-faint); font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.styleex { display:flex; gap:8px; padding:4px 0 12px; }   /* s72: the note now fills the room below */
.styleex figure { flex:1; margin:0; min-width:0; }
.styleex img { display:block; width:100%; aspect-ratio:3/4; object-fit:cover; border-radius:10px; border:1px solid var(--line); }
.styleex figcaption { margin-top:6px; text-align:center; font-size:12.5px; font-weight:600; color:var(--ink); }
.styleex figcaption small { display:block; font-weight:400; font-size:11px; color:var(--ink-faint); line-height:1.3; }
/* s74 — the '?' explainer: the full how-the-polish-works guide, scrollable if long. */
#stylesheet .pash-panel { max-height:86vh; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.styleguide-h { margin:0 0 12px; text-align:center; font-size:15px; font-weight:600; color:var(--ink); }
/* s76 (his call): the AI expectation-setter that opens the limpeza help — a plain, honest
   lead above the style images. */
.styleguide-lead { margin:0 0 14px; font-size:13px; line-height:1.5; color:var(--ink-soft); }
.styleguide h4 { margin:14px 0 3px; font-size:13px; font-weight:600; color:var(--accent); }
/* s76 (his call): the Gênero/body is one of the most consequential manequim settings — flag it. */
.styleguide-flag { margin-left:6px; padding:1px 6px; border-radius:6px; font-size:10px; font-weight:700;
  text-transform:uppercase; letter-spacing:.04em; vertical-align:1px;
  color:var(--accent); background:color-mix(in srgb, var(--accent) 14%, transparent); }
.styleguide p { margin:0; font-size:13px; line-height:1.5; color:var(--ink-soft); }
.styleguide-ex { margin:3px 0 0; padding-left:18px; }
.styleguide-ex li { font-size:13px; line-height:1.55; color:var(--ink-soft); }
.styleguide-foot { margin-top:14px !important; font-weight:500; color:var(--ink); }
/* the note hint is smaller than the typed text (16px stays, so iOS never zooms on focus). */
#polishsheet .personwrap textarea::placeholder { font-size:13px; }
.stylechip { flex:1; padding:9px 6px; border:1px solid var(--line-2); border-radius:var(--r-ctl);
  background:var(--paper); color:var(--ink-soft); font-family:var(--sans); font-size:12.5px;
  font-weight:600; cursor:pointer; }
.stylechip.on { border-color:var(--accent); color:var(--accent); background:var(--paper-2); }
/* The manequim body line (s76): sits under the chips, taps through to Gênero. The value is a
   light-plum pill (the ficha decided it); the untagged case swaps to a warn-amber pill. One
   button, full-width tap target; the chevron says it goes somewhere. */
.pash-body { display:flex; align-items:center; gap:7px; width:100%; margin:0 0 10px; padding:2px;
  border:0; background:none; font-family:var(--sans); font-size:12.5px; color:var(--ink-soft);
  text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.pash-body[hidden] { display:none; }
.pash-body-k { flex:none; }
.pash-body-pill { padding:3px 9px; border-radius:8px; font-size:11px; font-weight:700;
  color:var(--accent); background:var(--tint-2); }
.pash-body-pill.warn { text-transform:uppercase; letter-spacing:.03em;
  color:var(--warn); background:var(--warn-tint); }
.pash-body-chev { width:15px; height:15px; margin-left:auto; flex:none; fill:none;
  stroke:var(--ink-faint); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
.pash-body:active .pash-body-chev { stroke:var(--accent); }
/* The ✨ sheet's primary action is FILLED (s33): purple with white lettering, rounded to
   match its neighbours (Cancelar is 12px) — it's the main action, not a quiet outline.
   Scoped to #polishGo + #laRefazerBtn (s75, his call: 'Refazer com ajuste' matches 'Gerar
   imagem do look' — same AI-generate language) so the revisar .revrefine stays outlined. The
   sparkle svg inherits currentColor, so it turns white too. */
#polishGo, #laRefazerBtn { background:var(--accent); color:var(--on-accent); border-color:var(--accent);
  border-radius:12px; }
#polishGo:active, #laRefazerBtn:active { background:var(--accent-press); border-color:var(--accent-press); }
.menuact:disabled { opacity:.5; }
/* Field mic — dictate into a free-text field (título, notas, descrição da pessoa) */
.fieldmic { border:none; background:none; padding:6px; cursor:pointer; color:var(--accent);
  display:grid; place-items:center; border-radius:50%; -webkit-appearance:none; appearance:none; }
.fieldmic[hidden] { display:none; }
.fieldmic svg { width:20px; height:20px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* Optical centering: the mic glyph is top-heavy (solid capsule up top, thin stand below),
   so it reads high even when geometrically centered — nudge it down a hair. Scoped to the
   field + voice-note mics; the FAB mic is deliberately excluded. */
.fieldmic svg, .microw .mic svg { transform: translateY(6%); }
.fieldmic[data-state="rec"] { color:#fff; background:var(--red); animation:vxt-pulse 1.2s ease-in-out infinite; }
.fieldmic[data-state="busy"] { color:var(--ink-faint); opacity:.55; }
.txtsheet-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; }
.personwrap { position:relative; }
.personwrap textarea { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:16px; line-height:1.5;
  color:var(--ink); background:var(--paper); border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:12px 54px 12px 14px; min-height:70px; outline:none; resize:vertical; }
.personwrap textarea:focus { border-color:var(--accent); }
/* s70: a field with NO in-field mic (the Arrumar viewer) — the mic moved to the action row
   below, so the box gives the right padding back to the words. */
.personwrap.nomic textarea { padding-right:14px; }
.lb-perfect .searchactions-row .lineup-generate { margin-top:0; }   /* the row owns the air, not the button */
.lb-perfect .searchactions { margin-top:8px; }        /* s70 (his call): the row hugs the field… */
.lb-perfect .gencost { margin-top:16px; }             /* …and the créditos line gets the breathing room */
/* Salvar panel (the graduation moment): name + destino, same field treatment. */
.salvar-label, .salvar-dest { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:16px;
  color:var(--ink); background:var(--paper); border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:12px 14px; outline:none; -webkit-appearance:none; appearance:none; }
.salvar-label:focus, .salvar-dest:focus { border-color:var(--accent); }
.salvar-dest { margin-top:8px; }
.polishnote textarea::placeholder { font-size:14px; }   /* s50: the hint fits its two rows at 375pt */
.polishnote textarea { font-family:var(--sans); font-size:16px; color:var(--ink); background:var(--paper);
  border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 46px 12px 14px; min-height:64px; outline:none; resize:vertical; }
.polishnote textarea:focus { border-color:var(--accent); }
.polishnote { margin-bottom:10px; }
.personwrap .fieldmic { position:absolute; right:8px; bottom:8px; width:38px; height:38px; padding:0;
  background:var(--paper); border:1px solid var(--line-2); box-shadow:0 1px 3px rgba(0,0,0,.10); }
.personwrap .fieldmic svg { width:19px; height:19px; }
.personwrap .fieldmic[data-state="rec"] { background:var(--red); border-color:var(--red); color:#fff; box-shadow:none; }
/* the cover thumb wears the star, no frame (s50, his call) */
.thumbtag { position:absolute; left:50%; bottom:3px; transform:translateX(-50%); white-space:nowrap; background:var(--accent); color:var(--on-accent);
  font-size:9px; font-weight:700; letter-spacing:.06em; padding:2px 5px; border-radius:3px; line-height:1.4; }   /* centred (s50): the tiles grew, a left-hugging tag read as off */
.thumbtag.soft { background:var(--paper-2); color:var(--ink-soft); border:1px solid var(--line-2); font-size:8px; letter-spacing:.02em; padding:1px 4px; max-width:calc(100% - 6px); overflow:hidden; }
/* the globe on a thumb (s50): this photo is what a renter sees on the rede — plum by her
   choice, greyed on the cover (the hero there by definition). No globe = not shown. */
.thumb { position:relative; }
/* the marks (s50, his call): STAR = the cover, the photo the rede shows first; NUMBER =
   a chosen secondary photo, in the order a renter sees it (up to 5). No mark = not shown. */
/* Both marks wear the looks badge (s72, his call): a quiet purple glyph on a WHITE, fully
   opaque disc with a soft shadow — STAR = the cover, NUMBER = a chosen secondary rede photo
   (order 1–5). Calmer than the old solid-purple dot; the star's rounder path (template/JS)
   masks the strip's sub-pixel lean (the s51 saga) without pixel-snapping .thumb, so no
   tap-lag regression. 17px disc + 11px star = whole-pixel inset (docs/ui-language.md §24). */
.thumbmark { position:absolute; right:3px; top:3px; width:17px; height:17px; border-radius:50%; background:var(--paper); color:var(--accent);
  display:grid; place-items:center; font-size:10.5px; font-weight:700; line-height:1; box-shadow:0 1px 3px rgba(20,16,10,.25); }
.thumbmark.star svg { display:block; width:11px; height:11px; fill:var(--accent); stroke:none; }
.thumbmark.inline { position:static; display:inline-grid; vertical-align:-3px; margin-right:7px; }
/* a label/worn thumb being VIEWED in the hero (s50): a thin dashed outline, never the cover ring */
.thumb.viewing { border-color:var(--ink-soft); border-style:dashed; }
/* FOTOS PRA REDE — the disc (s50, his call): bottom-left of the hero, the corners that do
   work stay right; plum while the mode is on. Shows only with 2+ photos. */
.herorede { position:absolute; left:12px; bottom:12px; z-index:3; width:34px; height:34px; border:none; padding:0; border-radius:50%;
  background:var(--paper); display:grid; place-items:center; cursor:pointer; box-shadow:0 2px 10px rgba(20,16,10,.28); -webkit-tap-highlight-color:transparent; }
.herorede svg { display:block; width:18px; height:18px; fill:none; stroke:var(--accent); stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.herorede.on { background:var(--accent); }
.herorede.on svg { stroke:var(--on-accent); }
.hero.reframing .herorede { display:none; }
/* the mode's bar: the one line, the count, Concluir — the mode indicator (like the acervo's à venda bar) */
.redehow-eye { padding:4px 12px 0; }
.redehow-t { margin:0; padding:6px 12px 14px; font-size:14.5px; line-height:1.5; color:var(--ink); }
.redehow-go { display:block; width:100%; border:0; border-radius:12px; padding:13px; background:var(--accent); color:var(--on-accent); font:inherit; font-weight:600; font-size:15px; }
.thumbs.mode-rede .thumb[data-role="etiqueta"], .thumbs.mode-rede .thumb[data-role="referencia"], .thumbs.mode-rede .thumb[data-catid] { opacity:.45; }
.thumbs.mode-rede .thumbadd-wrap { display:none; }   /* an upload reloads the page — add first, then choose */
/* s74 (his call): rede mode gets a plum frame around the whole strip (common region — ties
   it to the far-off eye disc) + one small line under the row saying what to do. The frame
   only exists in the mode, so a resting ficha is unchanged. */
.thumbs.mode-rede { border:1.5px solid var(--accent); border-radius:12px; padding:9px;
  background:color-mix(in srgb, var(--accent) 7%, transparent); }
.rede-cue { display:none; }
.thumbs.mode-rede .rede-cue { display:block; flex:0 0 100%; margin:3px 1px 0;
  font-size:11px; line-height:1.3; color:var(--accent); text-align:center; }
/* the renter's strip on the rede piece page: the ficha's thumb dress, tap = view only */
.redethumbs { margin:-4px 0 14px; justify-content:center; }
.redethumbs .thumb { cursor:pointer; padding:0; background:var(--paper-2); border-radius:7px; }   /* the rede page's hero is rounded (.capshot 10px); its strip follows (s50) */
.redethumbs .thumb img { width:100%; height:100%; object-fit:cover; display:block; }
/* the photo is the door (s50): a bigger preview that carries the role tag; tap → the question */
.pash-prevbtn { position:relative; display:block; border:none; padding:0; background:none; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.pash-prevbtn:disabled { cursor:default; }
.pash-preview .pash-prevbtn img { width:120px; }
.pash-tag { position:absolute; left:50%; bottom:5px; transform:translateX(-50%); }
.pash-tag[hidden] { display:none; }
.pash-ask { padding:12px 12px 2px; }
.pash-ask[hidden] { display:none; }
.pash-eye { font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); font-weight:700; margin-bottom:6px; }
.segtoggle.segtoggle-3.pash-seg { width:100%; }   /* beats the Perfil's 214px */
.pash-segopt { flex:1; border:none; background:none; font:inherit; font-size:13.5px; color:var(--ink-soft); padding:9px 4px; cursor:pointer; border-left:1px solid var(--line); }   /* one divider: .segopt's own left line (no right one — it doubled) */
.pash-segopt:first-child { border-left:none; }
.pash-segopt.on { background:var(--accent); color:var(--on-accent); font-weight:600; }
.pash-hair { height:0.5px; background:var(--line); margin:12px 12px 4px; }
.thumbhint { font-size:11.5px; color:var(--ink-faint); margin-top:7px; letter-spacing:.01em; }
.board .bcard .sb { font-size:11.5px; color:var(--ink-faint); margin-top:4px; line-height:1.4; }

/* client view — render hero */
.cv-renders { display:flex; flex-direction:column; gap:10px; margin-bottom:14px; }
.cv-render { margin:0; }
.cv-render img { width:100%; border-radius:var(--r-ctl); border:1px solid var(--line); display:block; }

/* ============================================================
   UI polish (session 4) — bigger, more present form controls,
   no iOS tap-to-zoom (every field ≥16px), and text-links turned
   into real pill controls instead of bare "blue links".
   ============================================================ */

/* 16px on every input/select/textarea: kills iOS focus-zoom AND reads larger */
.form input, .form select, .form textarea,
.fld, select.fld, textarea.fld,
.addrow input, .closeform input, .cv-commentform input, .cv-name,
.tryonform textarea, .datefld input, .searchbar input, .shareurl,
.describe textarea {
  font-size: 16px;
}

/* roomier, more present fields */
.form input, .form select, .form textarea { padding: 14px 14px; border-radius: 9px; }
.form .f { gap: 8px; }
.lbl, .datefld span { font-size: 11.5px; letter-spacing: .12em; }
.fld { padding: 15px 15px; border-radius: 9px; margin-bottom: 11px; }
.datefld input { padding: 14px 14px; }
.closeform input, .cv-commentform input, .tryonform textarea { padding: 14px 14px; border-radius: 9px; }
.searchbar { padding-top: 13px; padding-bottom: 13px; }

/* material/filter chips: easier to read + tap */
.form .chip span { font-size: 14px; padding: 9px 15px; }
.filters .chip, .filters .chip span { font-size: 14px; padding: 8px 14px; }

/* buttons: present, not tiny */
.btn { font-size: 16px; padding: 16px; border-radius: 9px; border-width: 1.5px; }
.save { font-size: 16px; padding: 17px; border-radius: 9px; }
.addrow input { padding: 14px 15px; }
.addrow button { font-size: 15px; padding: 0 22px; border-radius: 9px; }

/* status chips bigger (look approval, etc.) */
.schip { font-size: 14px; padding: 9px 16px; }

/* text-links → present pill controls (no more bare "blue link") */
.editlink {
  border: 1.5px solid var(--line-2); border-radius: 2px;
  padding: 9px 18px; font-size: 14px; font-weight: 500; line-height: 1;
  color: var(--ink); background: var(--paper); text-decoration: none;
}
.editlink:active { border-color: var(--ink); background: var(--paper-2); }
/* scoped to the rentals header's text-link variant — the bare .addbtn selector was
   overriding the CIRCLE .addbtn (grid-centered) with inline-flex and no centering,
   so its + glyph sat off-centre (the s25 drift catch: one class, two components). */
.editlink.addbtn { display:inline-flex; align-items:center; gap:6px; color:var(--accent); border-color:var(--accent); }
.editlink.addbtn svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; }
.topactions { gap: 10px; }
.linkbtn {
  border: 1px solid var(--line-2); border-radius: 2px;
  padding: 8px 15px; font-size: 13px; color: var(--ink-soft); background: var(--paper);
}
.linkbtn:active { border-color: var(--accent); color: var(--accent); }

/* client approval surface: larger, more confident controls */
.cv-name { font-size: 16px; padding: 14px 22px; max-width: 360px; }
.cv-btn { font-size: 16px; padding: 14px 26px; }
.cv-commentform input { padding: 14px 14px; }
.cv-commentform button { font-size: 15px; padding: 0 20px; }
.tryonform button { font-size: 15px; padding: 14px 24px; }

/* ============================================================
   GALERIA — museum redesign (session 4). White ground, Archivo
   display, bare photo grid, hairline spec lists, ink UI, red
   held for the wordmark + alerts only.
   ============================================================ */
body { -webkit-font-smoothing:antialiased; }

.title h1 { font-family:var(--serif); font-weight:800; font-size:33px; letter-spacing:-.035em; }
.pagehead { align-items:baseline; padding-top:22px; padding-bottom:4px; }
.pagehead h1 { font-family:var(--serif); font-weight:800; font-size:29px; letter-spacing:-.035em; line-height:1; }
.pagehead .gear { align-self:center; }
.rd { color:var(--dot); }

.grp { font-family:var(--serif); font-weight:700; font-size:12.5px; letter-spacing:0; text-transform:none; color:var(--ink); }

.grid { gap:15px 13px; }
.tile { gap:7px; }
.tile .img { border:none; border-radius:2px; background:var(--paper-2); }
.tile .nm { font-family:var(--serif); font-weight:600; font-size:13px; letter-spacing:-.01em; line-height:1.2; }
.tile .sb { font-size:10px; letter-spacing:.07em; text-transform:uppercase; color:var(--ink-faint); }
.lens.on::after { background:var(--ink); }

.hero { border:1px solid var(--line); border-radius:var(--r-card); background:var(--paper-2); }   /* ficha hero rounded (s51, his call: rounder than the rede page is fine) */
.thumb { border-radius:2px; }
.thumbs .thumb { border-radius:9px; }   /* the ficha's photo strip rounds with the hero (s51) */
.eyebrow { font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); margin-bottom:9px; }
.tt h1 { font-family:var(--serif); font-weight:700; font-size:28px; letter-spacing:-.03em; line-height:1.03; }
.tt .sub { text-transform:uppercase; letter-spacing:.09em; font-size:11px; color:var(--ink-faint); margin-top:9px; }
.status { font-size:12px; letter-spacing:.04em; }
.avail-out { color:var(--red); }

.slabel { color:var(--ink-faint); font-size:10.5px; }
.row .k { text-transform:uppercase; letter-spacing:.11em; font-size:10.5px; color:var(--ink-faint); }
.row .v { font-family:var(--sans); font-weight:500; font-size:14.5px; }

.btn.danger { color:var(--red); border-color:var(--line-2); }
.btn.danger:active { border-color:var(--red); background:var(--card); }
.tag { border:1px solid var(--line-2); color:var(--ink-soft); border-radius:2px; }

.badge { border-radius:2px; }
.cont, .pc .img, .thumb, .rthumb, .editphoto, .cv-photo img, .cv-render img { border-radius:2px; }

/* client approval view — Galeria treatment */
.cv-brand { color:var(--ink); font-weight:700; letter-spacing:.28em; font-size:13px; }
.cv-brand .rd { color:var(--dot); }
.cv-head h1 { font-weight:700; font-size:30px; letter-spacing:-.03em; }
.cv-char { letter-spacing:.2em; }
.cv-label h2 { font-weight:700; letter-spacing:-.02em; font-size:22px; }
.cv-noimg { border-radius:2px; }
.cv-foot { font-weight:700; letter-spacing:.28em; }
.cv-state-approved { color:var(--ok); }
.cv-state-rejected { color:var(--red); }
.cv-btn.reject.on { background:var(--red); border-color:var(--red); }

/* ============================================================
   GALERIA polish — money, rentals, look board (session 4)
   ============================================================ */

/* /money — editorial financial headline; numbers big in Archivo */
.stats { grid-template-columns:repeat(3,1fr); gap:12px; margin-top:16px;
  border-top:1.5px solid var(--ink); border-bottom:1px solid var(--line); padding:17px 0; }
.stat { border:none; background:none; padding:0; text-align:left; }
.snum { font-family:var(--serif); font-weight:700; font-size:21px; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; line-height:1; }
.snum.ok { color:var(--ok); }
.snum.warn { color:var(--red); }
.slbl { font-size:9.5px; letter-spacing:.13em; margin-top:9px; }
.statnote { font-size:11.5px; }
.rbal { font-family:var(--serif); font-weight:700; font-size:16px; letter-spacing:-.01em;
  font-variant-numeric:tabular-nums; }
.rpaid { font-size:11px; }

/* rentals — alert states in red, line prices tabular */
.badge.overdue { color:var(--on-accent); background:var(--red); border-color:var(--red); }
.conflict-box { border-color:var(--red); color:var(--red); border-radius:2px; }
.conflict-box.warn { border-color:var(--line-2); color:var(--ink-soft); background:var(--paper-2); }
.riprice { font-variant-numeric:tabular-nums; font-size:13.5px; }
.riitem { padding:11px 2px; }

/* look board — squared remove chip, neutral overlay */
.bcard .bx button { background:rgba(20,20,20,.58); }

/* ============================================================
   Persistent nav (session 4) — bottom bar on every owner screen,
   FAB dead-center. Galeria: white blur, ink active, monochrome.
   ============================================================ */
.navbar { position:fixed; left:50%; transform:translateX(-50%); bottom:0; z-index:30;
  width:100%; max-width:480px; height:104px; background:color-mix(in srgb, var(--paper) 93%, transparent);
  backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);
  border-top:1px solid var(--line); display:flex; align-items:flex-start;
  justify-content:space-around; padding:13px 12px 0; padding-bottom:env(safe-area-inset-bottom); }
.navtab { position:relative; flex:1; display:flex; flex-direction:column; align-items:center; gap:5px;
  text-decoration:none; color:var(--ink-faint); font-size:9.5px; letter-spacing:.04em; }
.navtab svg { width:22px; height:22px; stroke:currentColor; stroke-width:1.5; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.navtab span { transition:color .12s; }
.navtab.on { color:var(--accent); }  /* s49: glyph AND label light — the glyph strokes currentColor */
.navtab.on span { color:var(--accent); font-weight:600; }
/* Bench count REPLACES the Mesa glyph (no pill). The face box is the icon's 22px slot so
   the label never shifts; the count shows only when the pile has pieces (.has-count).
   The count just tracks the TAB (s62, his call): grey (--ink-faint) like an unchosen tab's
   glyph+label, plum (--accent) when the tab IS chosen — so plum only ever appears on the active
   tab and never fakes a selection, and pink (the AI/credits pulse) is left out of the nav. */
.navtab-face { height:22px; display:grid; place-items:center; }
.navtab-count { display:none; font-size:19px; font-weight:700; line-height:1; color:var(--ink-faint);
  font-variant-numeric:tabular-nums; }
.navtab.has-count .navtab-glyph { display:none; }
.navtab.has-count .navtab-count { display:block; }
.navtab.on .navtab-count { color:var(--accent); }   /* chosen tab → the count lights plum with it */
.navfab { flex:none; width:70px; height:70px; border-radius:50%; background:var(--accent);
  color:var(--on-accent); display:grid; place-items:center; margin:-26px 6px 0;
  text-decoration:none; transition:transform .14s;
  /* Give the disc PRESSABLE shape depth (s35b, his pick #6): an inner bevel — a top
     highlight + a bottom inner-shadow read as a domed, pushable button — over the drop
     shadow that lifts it off the page (so it no longer merges into a purple button
     behind it). White-top / dark-bottom insets read as a bevel on ANY base colour, so
     this rides every glyph AND the red voice states with no per-theme tweak. */
  box-shadow:inset 0 2px 5px rgba(255,255,255,.18), inset 0 -5px 9px rgba(0,0,0,.20); }
/* Financeiro's door in the Trabalhos masthead (it's a room off Trabalhos now) */
.topmoney { color:var(--ink-faint); text-decoration:none; flex:none; display:flex; }
.topmoney svg { width:24px; height:24px; stroke:currentColor; stroke-width:1.5; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.topmoney:active { color:var(--accent); }
.navfab svg { width:30px; height:30px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; }
.navfab:active { transform:scale(.93); }
/* The FAB morphs through the voice states (TravelOps idiom) — the disc IS the
   control: + → mic (armed) → ■ stop (recording) → ↑ send (confirm). --red = live. */
.navfab .fab-plus { display:flex; align-items:center; justify-content:center; }
.navfab .fab-mic, .navfab .fab-stop, .navfab .fab-send, .navfab .fab-shuffle,
.navfab .fab-search { display:none; align-items:center; justify-content:center; }
/* Mesa-with-carousel (body.fab-sortear): idle glyph = the shuffle — tap IS Sortear there.
   Only the IDLE face changes; every voice state below replaces it just like the +. */
body.fab-sortear .navfab .fab-plus { display:none; }
body.fab-sortear .navfab .fab-shuffle { display:flex; }
body.fab-sortear .navfab.is-armed .fab-shuffle,
body.fab-sortear .navfab.is-recording .fab-shuffle,
body.fab-sortear .navfab.is-confirm .fab-shuffle { display:none; }
/* Empty mesa (body.fab-busca, mesa.html): tap already = buscar (how you fill the mesa),
   so the idle glyph is the magnifier, not a lying +. Same voice-state handling. */
body.fab-busca .navfab .fab-plus { display:none; }
body.fab-busca .navfab .fab-search { display:flex; }
body.fab-busca .navfab.is-armed .fab-search,
body.fab-busca .navfab.is-recording .fab-search,
body.fab-busca .navfab.is-confirm .fab-search { display:none; }
/* Rede pages (.navfab.fab-busca, set by base.html on /rede + /borrow): the verb is
   buscar-na-rede, so the idle glyph is the magnifier — the + promised "add". */
.navfab.fab-busca .fab-plus { display:none; }
.navfab.fab-busca .fab-search { display:flex; }
.navfab.fab-busca.is-armed .fab-search,
.navfab.fab-busca.is-recording .fab-search,
.navfab.fab-busca.is-confirm .fab-search { display:none; }
.navfab .fab-stop svg { fill:currentColor; stroke:none; width:26px; height:26px; }
.navfab .fab-mic svg, .navfab .fab-send svg { width:28px; height:28px; }
.navfab.is-arming { animation:fab-charge .45s ease-out forwards; }
@keyframes fab-charge {
  from { box-shadow:inset 0 2px 5px rgba(255,255,255,.18), inset 0 -5px 9px rgba(0,0,0,.20), 0 6px 18px var(--shadow-strong), 0 0 0 0 rgba(122,46,42,0); }
  to   { box-shadow:inset 0 2px 5px rgba(255,255,255,.18), inset 0 -5px 9px rgba(0,0,0,.20), 0 6px 18px var(--shadow-strong), 0 0 0 9px rgba(122,46,42,.18); }
}
.navfab.is-armed, .navfab.is-recording, .navfab.is-confirm { background:var(--red); }
.navfab.is-armed .fab-plus { display:none; }
.navfab.is-armed .fab-mic { display:flex; }
.navfab.is-recording .fab-plus, .navfab.is-recording .fab-mic { display:none; }
.navfab.is-recording .fab-stop { display:flex; }
.navfab.is-confirm .fab-plus, .navfab.is-confirm .fab-mic, .navfab.is-confirm .fab-stop { display:none; }
.navfab.is-confirm .fab-send { display:flex; }

/* Voice UI — self-fixed leaf elements, centered above the FAB (never covers it). */
.vxt-rec[hidden], .vxt-cancel[hidden] { display:none; }
.vxt-rec { position:fixed; left:50%; transform:translateX(-50%); bottom:124px; z-index:90;
  display:flex; align-items:center; gap:10px; background:var(--paper); border:1px solid var(--line-2);
  border-radius:22px; padding:9px 17px; box-shadow:0 4px 18px rgba(60,50,35,.18); }
.vxt-dot { width:9px; height:9px; border-radius:50%; background:var(--red); flex:none; animation:vxt-pulse 1.2s ease-in-out infinite; }
@keyframes vxt-pulse { 0%,100% { opacity:.35; } 50% { opacity:1; } }
.vxt-time { font-size:14px; color:var(--ink); font-variant-numeric:tabular-nums; font-weight:600; }
.vxt-lis { font-size:12px; color:var(--ink-soft); }
.vxt-cancel { position:fixed; left:50%; transform:translateX(-50%); bottom:124px; z-index:90;
  width:56px; height:56px; border-radius:50%; background:var(--paper); border:1px solid var(--line-2);
  color:var(--ink); display:flex; align-items:center; justify-content:center;
  box-shadow:0 4px 18px rgba(60,50,35,.18); cursor:pointer; }
.vxt-cancel svg { width:22px; height:22px; }
/* Working pill — cycles playful phrases while the query is transcribed + searched. */
.vxwork[hidden] { display:none; }
.vxwork { position:fixed; left:50%; transform:translateX(-50%); bottom:124px; z-index:90;
  display:flex; align-items:center; gap:9px; background:var(--paper); border:1px solid var(--line-2);
  border-radius:22px; padding:9px 18px; box-shadow:0 4px 18px rgba(60,50,35,.18);
  font-size:14px; color:var(--ink); font-weight:500; }
.vxwork-dot { width:8px; height:8px; border-radius:50%; background:var(--accent); flex:none; animation:vxt-pulse 1.1s ease-in-out infinite; }
.vxwork-ell span { display:inline-block; width:3px; height:3px; margin-left:2px; border-radius:50%; background:var(--ink-soft); animation:vxell 1.2s infinite; }
.vxwork-ell span:nth-child(2) { animation-delay:.2s; }
.vxwork-ell span:nth-child(3) { animation-delay:.4s; }
@keyframes vxell { 0%,60%,100% { opacity:.2; } 30% { opacity:1; } }

/* Language toggle (settings) — two pills, the checked one lights (via :has). */
.langtoggle { display:flex; gap:10px; margin:2px 0 6px; }
.langopt { flex:1; display:flex; align-items:center; justify-content:center; gap:8px; padding:13px;
  border:1px solid var(--line-2); border-radius:11px; font-size:14px; font-weight:500; color:var(--ink); cursor:pointer; }
.langopt input { position:absolute; opacity:0; width:0; height:0; }
.langopt:has(input:checked) { border-color:var(--accent); background:var(--paper-2); color:var(--accent); font-weight:600; }

/* Options swipe (s6) — the triage deck + the pile */
.swipeentry { display:flex; align-items:center; gap:9px; margin:2px 0 16px; padding:12px 16px;
  border:1px solid var(--line-2); border-radius:12px; background:var(--paper-2); color:var(--ink);
  text-decoration:none; font-size:14px; font-weight:500; }
.swipeentry svg { width:20px; height:20px; stroke:var(--accent); stroke-width:1.7; fill:none; flex:none; }
.swipeentry:active { background:var(--sand); }
/* s73 (his call, option A): the search note is information, not a warning — the light
   --card the ficha and tiles use, sized to its text, centred, and clear of the grid below.
   Sand (the warn tint) was doing the wrong job, full-width and pressed against the tiles. */
.fuzzynote { display:table; max-width:100%; box-sizing:border-box; margin:2px auto 18px; text-align:center;
  font-size:13px; line-height:1.45; color:var(--ink-soft); background:var(--card);
  border-radius:var(--r-ctl); box-shadow:0 1px 0 var(--line); padding:9px 16px; }
.mesabridge { text-align:center; padding:40px 24px; display:flex; flex-direction:column; align-items:center; }
.mesabridge-ic { width:52px; height:52px; color:var(--accent); opacity:.9; margin-bottom:18px; }
.mesabridge-ic svg { width:100%; height:100%; stroke:currentColor; stroke-width:1.3; fill:none; stroke-linejoin:round; }
.mesabridge-lbl { font-family:var(--serif); font-weight:500; font-size:19px; line-height:1.3; margin-bottom:7px; }
.mesabridge-sub { font-size:13.5px; color:var(--ink-faint); max-width:280px; line-height:1.5; margin-bottom:24px; }
.mesabridge-go { border:none; background:var(--accent); color:var(--on-accent); border-radius:12px;
  padding:14px 26px; font-family:var(--sans); font-size:14.5px; font-weight:600; cursor:pointer; }
.mesabridge-go:active { background:var(--accent-press); }
.mesabridge-go:disabled { opacity:.6; }
.briefsheet[hidden] { display:none; }
.briefsheet { position:fixed; inset:0; z-index:85; background:rgba(20,16,10,.35); }
.briefsheet-form { position:absolute; top:0; left:0; right:0; background:var(--paper);
  padding:calc(12px + env(safe-area-inset-top)) 14px 16px; box-shadow:0 6px 20px rgba(0,0,0,.12); }
.briefsheet-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.briefsheet-head b { font-family:var(--sans); font-size:15px; color:var(--ink); }
.briefsheet textarea { width:100%; box-sizing:border-box; border:1px solid var(--line-2);
  border-radius:11px; padding:12px 14px; font-family:var(--sans); font-size:15px; color:var(--ink);
  background:var(--paper); outline:none; resize:vertical; }
.briefsheet textarea:focus { border-color:var(--accent); }
.briefsheet-go { margin-top:9px; width:100%; border:none; background:var(--accent); color:var(--on-accent);
  border-radius:11px; padding:13px; font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.swipewrap { display:flex; flex-direction:column; min-height:calc(100vh - 92px); }
.swipedeck { position:relative; flex:1; margin:10px 0 16px; min-height:56vh; }
.swipecard { position:absolute; inset:0; display:flex; flex-direction:column; overflow:hidden;
  background:var(--card); border:1px solid var(--line); border-radius:20px;
  box-shadow:0 14px 34px -16px rgba(60,50,35,.34); touch-action:pan-y;
  user-select:none; -webkit-user-select:none; }
.swipeimg { flex:1; background:var(--paper-2); overflow:hidden; display:flex; }
.swipeimg img { width:100%; height:100%; object-fit:cover; display:block; }
.swipeimg > svg { width:84px; height:104px; margin:auto; opacity:.4; stroke:var(--ink-faint); stroke-width:1.3; fill:none; }
.swipemeta { padding:15px 18px 17px; background:var(--card); }
.swipename { font-size:20px; font-weight:700; letter-spacing:-.01em; }
.swipesub { font-size:13px; color:var(--ink-soft); margin-top:3px; }
.swipemeta .swrow { display:flex; gap:5px; margin-top:11px; }
.swipemeta .swd { width:22px; height:12px; border-radius:3px; }
.swipestamp { position:absolute; top:22px; padding:5px 14px; font-weight:800; font-size:22px;
  text-transform:uppercase; letter-spacing:.06em; border:3px solid; border-radius:var(--r-ctl); opacity:0;
  transition:opacity .08s; pointer-events:none; z-index:3; }
.swipestamp.like { right:20px; color:var(--accent); border-color:var(--accent); transform:rotate(13deg); }
.swipestamp.nope { left:20px; color:var(--red); border-color:var(--red); transform:rotate(-13deg); }
.swipecard.show-like .swipestamp.like { opacity:1; }
.swipecard.show-nope .swipestamp.nope { opacity:1; }
.swipeactions { display:flex; justify-content:center; gap:28px; padding:2px 0 8px; }
.swipebtn { width:62px; height:62px; border-radius:50%; border:1px solid var(--line); background:var(--paper);
  display:grid; place-items:center; cursor:pointer; box-shadow:0 5px 14px -5px rgba(60,50,35,.24); }
.swipebtn svg { width:26px; height:26px; stroke:currentColor; stroke-width:2.4; fill:none; stroke-linecap:round; }
.swipebtn.pass { color:var(--red); }
.swipebtn.maybe { color:var(--accent); }
.swipebtn:active { transform:scale(.92); }
.swipehint { text-align:center; font-size:12px; color:var(--ink-soft); padding-bottom:12px; }
/* Review gallery (s8) — garment cards with visible strips; mis-clusters caught at
   a glance. Split a stray photo, or join two adjacent cards at the seam. */
/* Canon sub-page head (s35): slim back-nav + big title, no floating count pill. */
.revback { display:inline-flex; align-items:center; gap:3px; color:var(--ink-soft);
  font-family:var(--sans); font-size:14px; text-decoration:none; margin:2px 0 6px; }
.revback svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.9; }
.revmast { margin-bottom:16px; }
.revsec { margin-top:22px; }
.revcap { margin-top:6px; }
.revgallery { margin:12px 0 0; }
/* Photo-first canon (s35): compact lifted card, a row for single-photo drafts. */
.revcard { position:relative; background:var(--card); border:1px solid var(--line); border-radius:14px;
  box-shadow:0 4px 14px var(--shadow); padding:10px; margin-bottom:10px; }
.revthumb { flex:none; width:66px; height:80px; border-radius:9px; overflow:hidden;
  background:var(--paper-2); display:block; }
.revthumb img { width:100%; height:100%; object-fit:cover; display:block; }
.revthumb svg { width:52%; height:52%; margin:24%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.5; }
/* Upload confirm-gate (s80): the AI-didn't-read-a-garment card — keep or discard, no ficha. */
.revcard-gate { border-color:var(--terra); }
.revgate { display:flex; align-items:flex-start; gap:13px; }
.revgate .revthumb { width:58px; height:74px; }
.revgate-main { flex:1; min-width:0; }
.revgate-t { font-size:15px; font-weight:600; color:var(--ink); }
.revgate-sub { font-size:12.5px; color:var(--ink-soft); margin-top:3px; line-height:1.4; }
.revgate-acts { display:flex; gap:9px; margin-top:12px; }
.revgate-discard, .revgate-keep { flex:1; text-align:center; font-size:13.5px; font-family:inherit;
  border-radius:10px; padding:9px 0; cursor:pointer; text-decoration:none; line-height:1.2; }
.revgate-discard { color:var(--ink-soft); background:none; border:1px solid var(--line-2); }
.revgate-keep { color:var(--accent); background:var(--tint); border:1px solid var(--accent); }
/* long-press delete (#46) — same gesture as tiles/trabalhos */
.revcard.holding .hold-ring { display:flex; background:rgba(40,28,48,.06); border-radius:14px; }
.revcard .hold-ring .trk { stroke:rgba(60,50,35,.18); }
.revcard .hold-ring .prg { stroke:var(--brick); }
.revstrip { display:flex; gap:8px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:2px; }
.revphoto { position:relative; flex:none; width:84px; aspect-ratio:2/3; border-radius:2px; overflow:hidden; background:var(--paper-2); }
.revphoto img { width:100%; height:100%; object-fit:cover; display:block; }
.revphoto svg { width:50%; height:50%; margin:25%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.5; }
.revsplit { position:absolute; left:0; right:0; bottom:0; border:none; padding:4px 0;
  background:rgba(20,16,10,.6); color:#fff; font-family:var(--sans); font-size:10.5px; letter-spacing:.03em;
  cursor:pointer; -webkit-appearance:none; appearance:none; }
.revsplit:active { background:var(--accent); }
.revphoto-del { position:absolute; top:3px; right:3px; width:20px; height:20px; padding:0; border:none;
  border-radius:50%; background:rgba(40,28,48,.62); color:#fff; font-size:14px; line-height:20px;
  text-align:center; cursor:pointer; -webkit-appearance:none; appearance:none; }
.revphoto-del:active { background:var(--brick); }
.revphoto-del:disabled { opacity:.5; }
.revphoto { cursor:pointer; }
.revphoto .revtag { left:4px; top:4px; bottom:auto; transform:none; }   /* the read at review (s50): top-left is the free corner — × top-right, separar the foot */
.revphoto .revtag[hidden] { display:none; }
.revbody { padding-top:0; }
.revopen { display:flex; align-items:center; gap:12px; text-decoration:none; color:var(--ink); }
/* multi-photo draft: the strip rides ABOVE the body (where splitting is possible),
   the body hairline-separated below — so single-photo cards never carry the strip. */
.revmulti .revstrip { margin-bottom:0; }
.revmulti .revbody { border-top:1px solid var(--line); margin-top:10px; padding-top:9px; }
.revbodymain { flex:1; min-width:0; }
.revchev { width:20px; height:20px; flex:none; fill:none; stroke:var(--ink-faint); stroke-width:1.7; }
.revopen:active { color:var(--accent); }
.revopen:active .revchev { stroke:var(--accent); }
.revname { font-size:16px; font-weight:700; letter-spacing:-.01em; }
.revname-todo { color:var(--terra); font-weight:600; font-size:16px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.revtodo { font-size:10.5px; letter-spacing:.05em; text-transform:uppercase; font-weight:700; color:var(--on-accent); background:var(--terra); border-radius:2px; padding:2px 6px; }
.revsub { font-size:12.5px; color:var(--ink-soft); margin-top:3px; }
.revtodonote { font-size:12.5px; color:var(--terra); text-align:center; line-height:1.45; margin:0 0 -4px; }
.revseam { display:flex; align-items:center; justify-content:center; gap:6px; width:auto; margin:2px auto 12px;
  padding:6px 16px; border:1px dashed var(--line-2); border-radius:9px; background:var(--paper);
  font-family:var(--sans); font-size:12px; color:var(--ink-soft); cursor:pointer; }
.revseam svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.7; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.revseam:active, .revseam.busy { border-color:var(--accent); color:var(--accent); }
.revbar { position:sticky; bottom:0; margin-top:18px; padding:12px 0 calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(to top, var(--paper) 70%, transparent); }
.revconfirmall { width:100%; border:none; background:var(--accent); color:var(--on-accent); border-radius:var(--r-ctl);
  padding:15px; font-family:var(--sans); font-size:15px; font-weight:600; cursor:pointer; }
.revconfirmall:disabled { opacity:.5; }
/* the precificar offer anchored as the page's closing next-step (was a lost foot line) */
.revfoot { border-top:1px solid var(--line); margin-top:22px; padding-top:4px; }
/* the receipt state's promoted next task — centered with the receipt, links in accent */
.emptynext { font-size:13.5px; color:var(--ink-soft); margin:4px 0 20px; }
.emptynext a { color:var(--accent); text-decoration:none; border-bottom:1px solid var(--tint-2); }
.revrefine { display:flex; align-items:center; justify-content:center; gap:8px; width:100%; margin:14px 0 0;
  border:1px solid var(--accent); background:var(--paper); color:var(--accent); border-radius:var(--r-ctl);   /* s70: the app's control radius, not the pre-s35 2px */
  padding:12px; font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.revrefine svg { width:17px; height:17px; fill:currentColor; stroke:none; }
.revrefine:disabled, .revrefine.busy { opacity:.6; }
.revrefinenote { font-size:12.5px; color:var(--brick); text-align:center; margin:8px 0 0; }
.revsec { margin-top:30px; }
.revsec:first-of-type { margin-top:18px; }

/* Ficha-completion cards (#37) — the ONE place the red→green completeness gradient
   reads as signal (completing fichas is the sole task here). --fc is set per card. */
.fgallery { display:flex; flex-direction:column; gap:10px; margin:14px 0 4px; }
.fcard { position:relative; background:var(--paper); border:1px solid var(--line); border-radius:10px;
  overflow:hidden; box-shadow:0 1px 3px rgba(40,28,48,.05); }
.fcard::before { content:""; position:absolute; left:0; top:0; bottom:0; width:5px; background:var(--fc, var(--line-2)); }
.fcard-face { display:flex; align-items:center; gap:12px; padding:11px 12px 11px 16px; text-decoration:none; color:var(--ink); }
.fcard-face:active { background:var(--paper-2); }
.fcard-thumb { flex:none; width:46px; height:58px; border-radius:5px; overflow:hidden; background:var(--paper-2); display:grid; place-items:center; }
.fcard-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.fcard-thumb svg { width:55%; height:55%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.5; }
.fcard-body { flex:1; min-width:0; }
.fcard-name { font-size:15px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fcard-gaps { display:flex; flex-wrap:wrap; gap:5px; margin-top:6px; }
.fgap { font-size:10.5px; font-weight:600; letter-spacing:.02em; padding:2px 8px; border-radius:20px;
  color:var(--fc, var(--brick)); background:color-mix(in srgb, var(--fc, var(--brick)) 12%, transparent); }
.fgap.soft { color:var(--ink-faint); background:var(--paper-2); font-weight:500; }
.fcard-face .revchev { width:18px; height:18px; flex:none; stroke:var(--ink-faint); stroke-width:1.6; fill:none; }
.fcard-ai { display:flex; align-items:center; justify-content:center; gap:7px; width:100%; border:none;
  border-top:1px solid var(--line); background:var(--paper-2); color:var(--accent); cursor:pointer;
  font-family:var(--sans); font-size:13px; font-weight:600; padding:11px; -webkit-appearance:none; appearance:none; }
.fcard-ai svg { width:15px; height:15px; fill:currentColor; stroke:none; }
.fcard-ai:disabled { opacity:.7; }

/* Guided capture (s8) — shoot a garment's angles, "Próxima peça", repeat. Each
   garment's shots are a user-defined cluster → one /importar draft (deterministic). */
.gcstage { margin:18px 0 0; }
.gchead { font-size:13px; font-weight:600; letter-spacing:.02em; color:var(--ink-soft); margin-bottom:10px; }
.gctray { display:flex; flex-wrap:wrap; gap:9px; }
.gcthumb { position:relative; width:78px; aspect-ratio:2/3; border-radius:2px; overflow:hidden; background:var(--paper-2); }
.gcthumb img { width:100%; height:100%; object-fit:cover; display:block; }
.gcthumb-x { position:absolute; top:3px; right:3px; width:20px; height:20px; border:none; border-radius:50%;
  background:rgba(20,16,10,.6); color:#fff; font-size:14px; line-height:1; cursor:pointer; padding:0; }
.gcadd { position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  width:78px; aspect-ratio:2/3; border:1px dashed var(--line-2); border-radius:2px; color:var(--ink-soft);
  background:var(--paper); cursor:pointer; }
.gcadd input { position:absolute; inset:0; opacity:0; cursor:pointer; }
.gcadd svg { width:24px; height:24px; stroke:currentColor; stroke-width:1.5; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.gcadd span { font-size:11px; }
.gchint { font-size:12px; color:var(--ink-faint); margin-top:9px; letter-spacing:.03em; }
.gcbar { display:flex; gap:10px; margin-top:20px; }
.gccap { font-size:12.5px; color:var(--accent); line-height:1.5; text-align:center; margin-top:12px; }
.gcnext { flex:1; border:1px solid var(--line-2); background:var(--paper); color:var(--ink); border-radius:2px;
  padding:13px; font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.gcdone { flex:1; border:none; background:var(--accent); color:var(--on-accent); border-radius:2px;
  padding:13px; font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.gcnext:disabled, .gcdone:disabled { opacity:.45; }
.gcdonelist { display:flex; flex-wrap:wrap; gap:7px; margin-top:16px; }
.gcchip { font-size:12px; color:var(--ink-soft); background:var(--paper-2); border-radius:2px; padding:5px 10px; }
.gcup[hidden] { display:none; }
.gcup { position:fixed; inset:0; z-index:95; background:rgba(20,16,10,.45); display:flex; align-items:center; justify-content:center; padding:24px; }
.gcup-panel { width:100%; max-width:340px; background:var(--paper); border-radius:6px; padding:22px; text-align:center; }
.gcup-msg { font-size:14px; color:var(--ink); margin-bottom:14px; }

/* Merge picker (s8) — from any piece, fold it into another (grouping is ongoing,
   not a one-time import step; a closeup shot months later joins an existing piece). */
.swipedone { text-align:center; padding:26px 0; }
.swipedone .hint { display:inline-block; margin-top:14px; font-size:14px; font-weight:500; color:var(--accent); text-decoration:none; }
.swipedone .hint:active { opacity:.6; }
.swipewrap.done { justify-content:center; }
.swipewrap.done .swipedeck,
.swipewrap.done .swipeactions,
.swipewrap.done .swipehint { display:none; }

.briefconfirm .bcintro { padding:14px 2px 6px; }
.briefconfirm .bcintro h1 { font-family:var(--serif); font-weight:500; font-size:22px; line-height:1.25; }
.briefconfirm .bcperson { margin-top:8px; font-size:13.5px; color:var(--ink-soft); line-height:1.5; }
.bcgroups { margin-top:14px; display:flex; flex-direction:column; gap:6px; }
.bcgroup { padding:12px 2px; border-top:1px solid var(--line); }
.bcgroup:first-child { border-top:none; }
.bchead { display:flex; align-items:baseline; justify-content:space-between; margin-bottom:9px; }
.bccat { font-size:13.5px; font-weight:500; letter-spacing:.01em; }
.bccount { font-size:12px; color:var(--ink-faint); }
.bcthumbs { display:flex; gap:7px; overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:2px; }
.bcthumb { flex:0 0 auto; width:60px; height:76px; border-radius:6px; overflow:hidden; background:var(--paper-2); }
.bcthumb img, .bcthumb svg { width:100%; height:100%; object-fit:cover; }
.bcthumb svg { stroke:var(--ink-faint); stroke-width:1; fill:none; padding:12px; }
.bcmissing { margin-top:16px; padding:12px 14px; border:1px dashed var(--line-2); border-radius:var(--r-ctl);
  display:flex; flex-wrap:wrap; align-items:center; gap:7px; }
.bcmisslabel { font-size:12.5px; color:var(--ink-soft); }
.bcmisspill { font-size:12px; padding:3px 9px; border-radius:11px; background:var(--paper-2); color:var(--ink-soft); }
.bcactions { margin-top:22px; display:flex; flex-direction:column; gap:10px; padding-bottom:24px; }
.bcactions .btn { text-decoration:none; text-align:center; }
.piletile { position:relative; }
.tilex { position:absolute; top:7px; right:7px; width:26px; height:26px; border-radius:50%; border:none;
  background:rgba(20,16,10,.55); color:#fff; font-size:16px; line-height:1; cursor:pointer; z-index:2; }
.tilex:active { background:var(--red); }

/* Cast / actors (s6) — the photo-of-everybody grid on a produção */
/* per-expense character attribution select (small, quiet) */
.expattr { margin-top:3px; }
.expattr select { border:none; background:none; font-family:var(--sans); font-size:11px;
  color:var(--accent); padding:0; cursor:pointer; -webkit-appearance:none; appearance:none; outline:none; }
/* Figuração — the special crowd line, count × per-head, with its revision history */
/* Mesa "montando para {character}" context bar — the Mesa opened from a character card */
.montarctx { display:flex; align-items:center; justify-content:space-between; gap:10px;
  margin:2px 0 14px; padding:9px 14px; border-radius:11px; text-decoration:none;
  background:color-mix(in srgb, var(--accent) 12%, var(--paper)); color:var(--ink); }
.montarctx-body { font-size:13px; }
.montarctx-body b { color:var(--accent); }
.montarctx-x { font-size:20px; line-height:1; color:var(--ink-faint); flex:none; }
.salvar-destfixed { font-size:14px; color:var(--ink-soft); padding:2px 0; }
.figu { margin:16px 0 4px; padding:14px 15px; border:1px solid var(--line); border-radius:12px; background:var(--card); }
.figu-head { display:flex; align-items:baseline; justify-content:space-between; }
.figu-head .slabel { margin:0; }
.figu-tot { font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; }
.figu-now { font-size:13px; color:var(--ink-soft); margin:6px 0 10px; }
/* Figuração aggregate (s22): the per-scene buckets, each a row into /cena, + the geral label. */
.figu-scenes { display:flex; flex-direction:column; margin:8px 0 12px; }
.figu-scene { display:flex; align-items:baseline; justify-content:space-between; gap:12px; padding:9px 2px; border-bottom:1px solid var(--hair); text-decoration:none; color:inherit; }
.figu-scene-cena { font-size:13.5px; color:var(--ink); }
.figu-scene-n { font-size:12.5px; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.figu-scene-n b { color:var(--ink); }
.figu-geral-lbl { font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-faint); margin:4px 2px 8px; }
/* Figuração as a QUIET disclosure on /cena (s22): stays collapsed when the scene has none;
   the summary carries the gist (count, or the alert chip) so you never open an empty form. */
.figu-drop { margin-top:24px; }
.figu-drop > summary { list-style:none; cursor:pointer; display:flex; align-items:center; gap:8px; font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); padding:4px 2px; }
.figu-drop > summary::-webkit-details-marker { display:none; }
.figu-drop > summary::after { content:"⏷"; letter-spacing:0; font-size:10px; color:var(--ink-faint); margin-left:auto; transition:transform .15s; }
.figu-drop[open] > summary::after { transform:rotate(180deg); }
.figu-drop > summary b { color:var(--ink); }
.figu-drop > summary .scn-fig-alert { text-transform:none; letter-spacing:0; }
.figu-drop .rev-banner, .figu-drop .figu-now, .figu-drop .figu-form { margin-top:12px; }
.figu-now b { color:var(--ink); font-size:15px; }
.figu-note { color:var(--ink-faint); }
.figu-form { display:grid; grid-template-columns:60px 1fr auto; gap:8px; align-items:center; }
.figu-form input { box-sizing:border-box; width:100%; min-width:0; border:1px solid var(--line); border-radius:var(--r-ctl);
  padding:8px 10px; font-family:var(--sans); font-size:13px; color:var(--ink); background:var(--paper); outline:none; }
.figu-form input[name="note"] { grid-column:1 / 3; }
.figu-form input:focus { border-color:var(--accent); }
.figu-form button { grid-column:3; grid-row:1 / 3; align-self:stretch; border:none; border-radius:var(--r-ctl);
  background:var(--accent); color:var(--on-accent); font-family:var(--sans); font-size:13px; font-weight:600;
  padding:0 14px; cursor:pointer; }
.figu-hist { margin-top:11px; }
.figu-hist summary { font-size:12px; color:var(--accent); cursor:pointer; }
.figu-hist ul { list-style:none; margin:8px 0 0; padding:0; display:flex; flex-direction:column; gap:6px; }
.figu-hist li { font-size:12px; color:var(--ink-soft); display:flex; justify-content:space-between; gap:10px;
  padding-bottom:6px; border-bottom:1px solid var(--line); }
.figu-hist li b { color:var(--ink); }
.figu-when { color:var(--ink-faint); white-space:nowrap; flex:none; }
/* the distribution ledger — Σ previstos vs verba */
.ledger { margin:2px 0 16px; padding:13px 15px; border:1px solid var(--line); border-radius:12px; background:var(--card); }
.ledger-head { display:flex; align-items:baseline; justify-content:space-between; font-size:13px; }
.ledger-head > span:first-child { color:var(--ink-soft); letter-spacing:.02em; }
.ledger-val { font-size:14px; font-variant-numeric:tabular-nums; }
.ledger-of { color:var(--ink-faint); font-weight:400; }
.ledger-track { height:7px; border-radius:999px; background:var(--paper-2); margin:10px 0 8px; overflow:hidden; }
.ledger-track > span { display:block; height:100%; width:0; border-radius:999px; background:var(--accent);
  transition:width .25s ease; }
.ledger.over .ledger-track > span { background:var(--danger); }
.ledger-note { font-size:11.5px; color:var(--ink-faint); }
.ledger.over .ledger-note { color:var(--danger); font-weight:600; }
.ledger-noverba { color:var(--ink-faint); }

/* Compose — zone reels + tray (s6) */
.reel { display:flex; gap:10px; overflow-x:auto; padding:2px 2px 8px; scroll-snap-type:x proximity;
  -webkit-overflow-scrolling:touch; }
.reel::-webkit-scrollbar { display:none; }
/* s78 (his call): exactly THREE accessories fit the row, no far-right crop. A fixed 104px
   made 3 + 2 gaps (332px) overflow the ~303px reel, cropping the 3rd. Sizing to a third of
   the row (minus the two 10px gaps) fits 3 cleanly at any phone width; more scroll. */
.reelpiece { flex:0 0 calc((100% - 20px) / 3); scroll-snap-align:start; cursor:pointer; position:relative; }
.reelpiece input { position:absolute; opacity:0; width:0; height:0; }
.reelimg { display:flex; position:relative; aspect-ratio:2/3; border-radius:12px; overflow:hidden; background:var(--paper-2);
  border:2px solid transparent; }
.reelimg img { width:100%; height:100%; object-fit:cover; display:block; }
/* s75 spike C: a contain-fit accessory (a wide necklace) shows WHOLE on its own ground
   (the reelimg inline bg_hex), matching the silhouette slots' .sq-contain. */
.reelimg img.sq-contain { object-fit:contain; }
/* s76 (his call): the accessory tile's 2px transparent border shows the inline bg_hex ground
   under it (spike C) as a faint hairline ring at rest and on hold. Accessories have no
   checked-ring that needs the border, so drop it — the image fills edge to edge, no ring. */
.reelacc .reelimg { border:0; }
.reelimg > svg { width:44px; height:56px; margin:auto; opacity:.4; stroke:var(--ink-faint); stroke-width:1.3; fill:none; }
/* Selected (s36c): drop the hard accent hairline for a softer tint halo + a ✓ badge —
   the pin idiom, cleaner than a purple frame. Applies to every reel (zones + accessories). */
.reelpiece input:checked + .reelimg { box-shadow:0 0 0 3px var(--tint-2); }
.reelpiece input:checked + .reelimg::after { content:"✓"; position:absolute; top:6px; right:6px;
  width:20px; height:20px; border-radius:50%; background:var(--accent); color:var(--on-accent);
  display:grid; place-items:center; font-size:12px; font-weight:700; box-shadow:0 1px 4px var(--shadow); }
.reelnm { display:block; font-size:11px; color:var(--ink-soft); margin-top:5px; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; text-align:center; }
.reelpiece input:checked ~ .reelnm { color:var(--accent); font-weight:600; }
/* Accessories (s44, his pick — option B): the "in the look" signal lives in the NAME PILL,
   never on the image. The faint frame and the ✓ badge are dropped, so the thumbnail stays
   fully visible and the top-right corner belongs to the rede globe alone (no collision). */
.reelacc input:checked + .reelimg { box-shadow:none; }
.reelacc input:checked + .reelimg::after { content:none; }
.reelacc input:checked ~ .reelnm { display:block; width:fit-content; max-width:100%;
  margin:5px auto 0; padding:3px 9px; box-sizing:border-box; border-radius:var(--r-pill);
  background:var(--accent); color:var(--on-accent); font-weight:600; }
.reelacc input:checked ~ .reelnm::before { content:"✓ "; }
.composelabel { margin-top:16px; }
.pilecta { display:flex; gap:10px; margin:2px 0 14px; }
.pilecta > * { flex:1; margin:0; }
.pilebtn { display:block; box-sizing:border-box; width:100%; text-align:center; text-decoration:none;
  border:1px solid var(--accent); color:var(--accent); background:var(--paper); border-radius:11px;
  padding:12px; font-family:var(--sans); font-size:14px; font-weight:600; cursor:pointer; }
.pilebtn.primary { background:var(--accent); color:var(--on-accent); }

/* WhatsApp handoff (s6) — hand the conversation off, pre-filled */
/* the borrower page's second ping — born unstyled in s29 (the svg filled the .btn
   and its circles rendered as three giant black dots on any share-capable phone);
   only [data-share]-capable devices ever reveal it, so no desktop check caught it */
.shareped { display:inline-flex; align-items:center; justify-content:center; gap:8px; }
.shareped svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.wabtn { display:inline-flex; align-items:center; gap:8px; margin:2px 0 8px; padding:11px 16px;
  border-radius:11px; background:var(--wa); color:#fff; text-decoration:none; font-size:14px; font-weight:600; }
.wabtn svg { width:19px; height:19px; }
.wabtn:active { filter:brightness(.93); }
/* WhatsApp DIRECT-LINE icon (s33 S/N): the "Falar no WhatsApp" banner spent prime real
   estate on a SECONDARY, relationship-gated action (transacting_with reveals the number,
   so it only shows to people already dealing with this acervo). Demoted to a quiet round
   white balloon on green — a recognizable direct line that never outranks the pieces.
   Bare = in a topbar (piece page); --cover floats it on the storefront's landscape header. */
.waicon { display:inline-grid; place-items:center; width:40px; height:40px; border-radius:50%;
  background:var(--wa); box-shadow:0 2px 6px rgba(20,16,10,.28); flex:none; text-decoration:none; }
.waicon svg { width:21px; height:21px; fill:#fff; stroke:none; }
.waicon:active { filter:brightness(.93); }
.waicon--cover { position:absolute; right:12px; top:100%; margin-top:8px; z-index:2; }   /* just below the banner line, same right axis (off the photo) */

/* Expense / job ledger (s6) */
.exptotal { display:flex; align-items:baseline; gap:9px; margin:4px 0 8px; }
.exptotalv { font-family:var(--serif); font-size:26px; font-weight:700; letter-spacing:-.02em; }
.exptotall { font-size:12px; color:var(--ink-soft); }
.expcats { display:flex; flex-wrap:wrap; gap:7px; margin-bottom:12px; }
.expcat { font-size:12px; color:var(--ink-soft); background:var(--paper-2); border:1px solid var(--line);
  border-radius:20px; padding:4px 11px; }
.expcat b { color:var(--ink); }
.explist { display:flex; flex-direction:column; margin-bottom:10px; }
.exprow { display:flex; align-items:center; gap:11px; padding:10px 2px; border-bottom:1px solid var(--line); }
.expthumb { flex:none; width:42px; height:42px; border-radius:var(--r-ctl); overflow:hidden; background:var(--paper-2);
  border:1px solid var(--line); }
.expthumb img { width:100%; height:100%; object-fit:cover; display:block; }
.expmain { flex:1; min-width:0; }
.expvendor { font-size:14px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.expmeta { font-size:12px; color:var(--ink-soft); }
.expval { flex:none; font-size:14px; font-weight:600; }
.expdel { flex:none; border:none; background:none; color:var(--ink-faint); font-size:19px; line-height:1;
  cursor:pointer; padding:0 2px; }
.expdel:active { color:var(--red); }
.expupload { display:inline-flex; align-items:center; gap:9px; margin-top:4px; padding:11px 16px;
  border:1px solid var(--line-2); border-radius:11px; background:var(--paper-2); color:var(--accent);
  font-size:14px; font-weight:600; cursor:pointer; }
.expupload input[type=file] { position:absolute; width:1px; height:1px; opacity:0; }
.expupload svg { width:19px; height:19px; stroke:var(--accent); stroke-width:1.6; fill:none; }
.exprowbtns { display:flex; flex-wrap:wrap; align-items:center; gap:10px; }
.exprowbtns .expadd { margin:0; }
.exprowbtns .expupload { margin-top:0; }
/* author display beats the UA [hidden] reset — the s33 Android gallery doors ship
   `hidden` and are revealed by JS on Android only; without this they'd show for everyone. */
.expupload[hidden], .charadd[hidden] { display:none; }
.expturnin { display:inline-flex; align-items:center; gap:9px; padding:11px 16px; border-radius:11px;
  background:var(--accent); color:var(--on-accent); text-decoration:none; font-size:14px; font-weight:600; }
.expturnin svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.6; fill:none; }

/* Batch import + review (s6) */
.bigpick { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px;
  margin:16px 0; padding:44px 20px; border:2px dashed var(--line-2); border-radius:16px;
  background:var(--paper-2); color:var(--accent); font-size:15px; font-weight:600; cursor:pointer; text-align:center; }
.bigpick input[type=file] { position:absolute; width:1px; height:1px; opacity:0; }
.bigpick svg { width:32px; height:32px; stroke:var(--accent); stroke-width:1.7; fill:none; stroke-linecap:round; }
.impbar { height:8px; border-radius:6px; background:var(--line); overflow:hidden; margin:22px 0 10px; }
.impbar span { display:block; height:8px; width:0; background:var(--accent); border-radius:6px; transition:width .2s; }
.impcount { font-size:13px; color:var(--ink-soft); text-align:center; }
.impdoneh { font-family:var(--serif); font-size:20px; font-weight:700; text-align:center; margin:24px 0 12px; }
#importdone { text-align:center; }
.reviewedit { display:inline-block; margin-top:11px; font-size:13px; color:var(--accent); text-decoration:none; font-weight:600; }
/* Quicklog (s14) — the light-tier capture: thumb · AI name · price, one row per item.
   The floor of the fill engine: photo + price, no ficha. */
.qlprog { font-size:12.5px; color:var(--ink-soft); margin:14px 2px; }
.qlbulk { display:flex; align-items:center; gap:8px; margin:12px 2px 10px; padding:9px 12px;
  border:1px solid var(--line-2); border-radius:11px; background:var(--paper-2); }
.qlbulk[hidden] { display:none; }
.qlbulk-l { font-size:13px; color:var(--ink-soft); font-weight:500; }
.qlbulk input { flex:1; min-width:0; border:none; background:none; font-family:var(--sans); font-size:16px; color:var(--ink); outline:none; }
.qlbulk button { border:none; background:var(--accent); color:var(--on-accent); font-family:var(--sans); font-size:12.5px; font-weight:600; padding:8px 14px; border-radius:20px; cursor:pointer; flex:none; }
#qllist { display:flex; flex-direction:column; gap:8px; margin-top:6px; }
.qlrow { position:relative; overflow:hidden; display:flex; align-items:center; gap:12px; padding:6px; border:1px solid var(--line); border-radius:12px; background:var(--paper); transition:border-color .15s, opacity .18s; touch-action:pan-y; }
.qlrow.priced { border-color:color-mix(in srgb, var(--accent) 45%, var(--line)); }
.qlrow.saving { opacity:.55; }
.qlrow.deleting { opacity:0; }
/* Long-press to delete: the red bar fills over the hold; releasing before it fills cancels. */
.qlhold { position:absolute; left:0; top:0; bottom:0; width:0; background:color-mix(in srgb, var(--danger) 22%, transparent);
  pointer-events:none; z-index:0; }
.qlrow.holding { border-color:var(--danger); }
.qlrow.holding .qlhold { width:100%; transition:width .55s linear; }
.qlrow > :not(.qlhold) { position:relative; z-index:1; }
.qlthumb { width:52px; height:70px; flex:none; border-radius:var(--r-ctl); overflow:hidden; background:var(--paper-2); display:grid; place-items:center; }
.qlthumb img { width:100%; height:100%; object-fit:cover; display:block; }
.qlthumb svg { width:46%; height:46%; stroke:var(--ink-faint); stroke-width:1.2; fill:none; opacity:.5; }
.qlmeta { flex:1; min-width:0; }
.qlname { font-size:14px; font-weight:500; color:var(--ink); line-height:1.3;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:hidden; }
.qlprice { display:flex; align-items:center; gap:4px; flex:none; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:8px 10px; background:var(--paper); }
.qlprice span { font-size:13px; line-height:20px; color:var(--ink-faint); }
/* s70: the field and the R$ share one explicit 20px line box — iOS Safari gives text inputs an
   inner padding + native box of its own, which flex centring can't see (the 'preço' sat low). */
.qlprice input { width:60px; height:20px; line-height:20px; padding:0; margin:0; border:none; background:none;
  -webkit-appearance:none; appearance:none; border-radius:0; font-family:var(--sans); font-size:16px; color:var(--ink);
  outline:none; text-align:right; }
/* s70: no placeholder — the R$ already says 'a price goes here' (and iOS never centred it) */
.qldonelink { margin-top:18px; }
.reviewbanner { display:flex; align-items:center; gap:9px; margin:2px 0 12px; padding:12px 16px; border-radius:12px;
  background:var(--sand); color:var(--ink); text-decoration:none; font-size:14px; font-weight:600; }
.reviewbanner svg { width:19px; height:19px; stroke:var(--accent); stroke-width:1.7; fill:none; flex:none; }
.reviewbanner .rbn { margin-left:auto; color:var(--accent); }

/* FAB re-port (s6) — it's a <button> now; action sheet on tap */
button.navfab { border:none; padding:0; font:inherit; -webkit-appearance:none; appearance:none; cursor:pointer; }
.fabsheet[hidden] { display:none; }
.fabsheet { position:fixed; inset:0; z-index:80; display:flex; align-items:flex-end; }
.fabsheet-backdrop { position:absolute; inset:0; background:rgba(20,16,10,.42); }
.fabsheet-panel { position:relative; width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:20px 20px 0 0; padding:10px 12px calc(16px + env(safe-area-inset-bottom));
  box-shadow:0 -8px 30px rgba(0,0,0,.22); }
.fabgroup { margin-top:10px; }
.fabgroup:first-child { margin-top:2px; }
/* The intake fork has no label (s23) — without it the first item hugs the sheet's
   rounded top. Restore the top breathing room so it matches the gap BETWEEN items. */
.fabgroup-lead { padding-top:6px; }
.fabgroup + .fabgroup { border-top:1px solid var(--line); padding-top:8px; }
.fabgroup-label { margin:0 0 2px 12px; font-size:11px; font-weight:600; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink-faint); }
.fabact { display:flex; align-items:center; gap:14px; width:100%; box-sizing:border-box; padding:14px 12px;
  text-decoration:none; color:var(--ink); border-radius:12px; text-align:left;
  border:none; background:none; font:inherit; -webkit-appearance:none; appearance:none; cursor:pointer; }
.fabact:active { background:var(--paper-2); }
.fabadd { position:relative; }
.fabadd input[type=file] { position:absolute; inset:0; width:100%; height:100%; margin:0; padding:0; border:0; opacity:0; cursor:pointer; -webkit-appearance:none; appearance:none; font-size:16px; }
.fabact svg { width:24px; height:24px; stroke:var(--accent); stroke-width:1.6; fill:none; flex:none; stroke-linecap:round; stroke-linejoin:round; }
/* Glyph-only custodial sheet: big round targets, grouping by weight (filled =
   adicionar, outlined = encontrar), hairline divider between the groups. */
.fabglyphs { display:flex; align-items:center; justify-content:center; gap:16px; padding:16px 0 12px; }
.fabglyph { position:relative; width:72px; height:72px; border-radius:50%; flex:none; cursor:pointer;
  border:1px solid var(--line-2); background:var(--paper-2); color:var(--ink);
  display:grid; place-items:center; padding:0; }
.fabglyph.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.fabglyph svg { width:30px; height:30px; stroke:currentColor; stroke-width:1.6; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.fabglyph:active { transform:scale(.93); }
.fabglyph input[type=file] { position:absolute; inset:0; width:100%; height:100%; margin:0; padding:0; border:0; opacity:0; cursor:pointer; -webkit-appearance:none; appearance:none; font-size:16px; border-radius:50%; }
/* the labeled doors (s24): hierarchy + consequence text. The bolt goes CREAM (paper
   ground, hairline) so the eye reads primary/secondary before reading a word. */
.fabglyphs.labeled { flex-direction:column; gap:20px; padding:18px 0 14px; }
.fabdoor { display:flex; flex-direction:column; align-items:center; gap:3px; text-align:center; }
.fabdoor b { font-size:14.5px; font-weight:600; color:var(--ink); margin-top:6px; }
.fabdoor small { font-size:12px; color:var(--ink-soft); max-width:250px; line-height:1.45; }
.fabdoor.sub .fabglyph { width:56px; height:56px; }
.fabdoor.sub .fabglyph svg { width:24px; height:24px; }
.fabdoor.sub b { font-size:13px; font-weight:500; }
.fabglyph.quiet { background:var(--paper); border:1px solid var(--line-2); color:var(--ink-soft); }
/* loja category chips — the storefront finally gets the same filter grammar */
/* The loja's filter row (s31, third pass): ONE fchip → optsheet, the archive's own
   idiom — the grid is the census, so the filter costs a single quiet control. This
   container only supplies the nopad page's side padding. */
.vchips { display:flex; gap:8px; padding:4px 18px 12px; }
.fabglyph-div { width:1px; height:44px; background:var(--line-2); flex:none; }
.fabact span { display:flex; flex-direction:column; }
.fabact b { font-size:15px; font-weight:600; }
.fabact small { font-size:12px; color:var(--ink-soft); }
.fabhint { margin:2px 12px 6px 50px; font-size:12px; color:var(--ink-faint); line-height:1.4; }
.fabhint[hidden] { display:none; }
.fabhint b { color:var(--ink-soft); font-weight:600; }
.fabsheet-cancel { width:100%; margin-top:6px; padding:14px; border:none; background:var(--paper-2);
  border-radius:12px; font-family:var(--sans); font-size:15px; font-weight:600; color:var(--ink-soft); cursor:pointer; }

/* Piece "⋯" overflow — low-frequency manage actions (merge / trash) off the topbar */
.topmenu { border:none; background:none; padding:6px; margin:-6px; cursor:pointer; color:var(--ink-soft);
  -webkit-appearance:none; appearance:none; display:grid; place-items:center; }
.topmenu svg { width:22px; height:22px; fill:currentColor; }
.menusheet[hidden] { display:none; }
.menusheet { position:fixed; inset:0; z-index:96; display:flex; align-items:flex-end; }
.menusheet-backdrop { position:absolute; inset:0; background:rgba(20,16,10,.42); }
.menusheet-panel { position:relative; width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:20px 20px 0 0; padding:10px 12px calc(16px + env(safe-area-inset-bottom)); box-shadow:0 -8px 30px rgba(0,0,0,.22); }
.menuact { display:flex; align-items:center; gap:14px; width:100%; box-sizing:border-box; padding:15px 12px;
  border:none; background:none; font:inherit; text-align:left; color:var(--ink); border-radius:12px; cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.menuact:active { background:var(--paper-2); }
.menuact[hidden] { display:none; }  /* display:flex above would otherwise defeat the hidden attr */
.menuact svg { width:22px; height:22px; stroke:var(--accent); stroke-width:1.7; fill:none; flex:none; stroke-linecap:round; stroke-linejoin:round; }
.menuact span { font-size:15px; font-weight:500; }
.menuact span em { display:block; font-style:normal; font-size:12px; font-weight:400; color:var(--ink-faint); margin-top:1px; }
.menusheet-head { padding:6px 12px 10px; display:flex; flex-direction:column; gap:2px; }
.menusheet-head b { font-size:15px; font-weight:600; color:var(--ink); }
.menusheet-head small { font-size:12.5px; color:var(--ink-faint); }
.menusheet-note { font-size:12.5px; color:var(--ink-faint); line-height:1.5; padding:0 12px 6px; margin:0; }
.menuact.danger { color:var(--red); }
.menuact.danger svg { stroke:var(--red); }
.menusheet form { margin:0; }
.menusheet-cancel { width:100%; margin-top:6px; padding:14px; border:none; background:var(--paper-2);
  border-radius:12px; font-family:var(--sans); font-size:15px; font-weight:600; color:var(--ink-soft); cursor:pointer; }
/* s65 (his call): a destructive action in a sheet is a real BUTTON now, not a text row — the
   danger twin of .menusheet-cancel: a soft red-wash fill so it pairs with Cancelar and reads
   as a button without a loud solid red. */
.menusheet-danger { width:100%; margin-top:6px; padding:14px; border:none; border-radius:12px;
  background:color-mix(in srgb, var(--danger) 13%, var(--card)); color:var(--danger);
  font-family:var(--sans); font-size:15px; font-weight:600; display:flex; align-items:center;
  justify-content:center; gap:9px; cursor:pointer; -webkit-appearance:none; appearance:none; }
.menusheet-danger svg { width:19px; height:19px; stroke:var(--danger); stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:none; }
.menusheet-danger[hidden] { display:none; }
.menusheet-danger:active { background:color-mix(in srgb, var(--danger) 22%, var(--card)); }

/* Typed search — a clean autofocused overlay from the FAB (replaces the top bar) */
.searchsheet[hidden] { display:none; }
.searchsheet { position:fixed; inset:0; z-index:85; background:rgba(20,16,10,.35); }
/* "Onde fica" (s62, was a chip row): her places collapse into one chip + a dropdown. Shown
   only while the field is empty; scales past the one-line band the chips broke. */
.ondefica { position:relative; margin:0; flex:none; }   /* s70: first in the action row */
/* mic engaged (recording / transcribing) → the chip is inert: a place tap would navigate
   away and drop the dictation. Dimmed, not hidden — hiding would make Buscar jump wide,
   and that jump already means 'you typed something'. */
.searchactions:has(.searchmic[data-state="rec"]) .ondefica-chip,
.searchactions:has(.searchmic[data-state="busy"]) .ondefica-chip { opacity:.45; pointer-events:none; }
.ondefica[hidden] { display:none; }
.ondefica-chip { display:inline-flex; align-items:center; gap:5px; padding:7px 11px 7px 9px;
  border:1px solid var(--line-2); border-radius:var(--r-pill); background:var(--paper-2); color:var(--ink-soft);
  font-family:var(--sans); font-size:12.5px; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.ondefica-chip[aria-expanded="true"] { background:var(--tint); color:var(--accent); border-color:var(--accent); }
.ondefica-pin { width:14px; height:14px; flex:none; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.ondefica-chev { width:14px; height:14px; flex:none; fill:none; stroke:currentColor; stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; transition:transform .16s; }
.ondefica-chip[aria-expanded="true"] .ondefica-chev { transform:rotate(180deg); }
.ondefica-menu { position:absolute; left:0; top:calc(100% + 6px); z-index:2; min-width:180px; max-width:min(78vw,320px);
  max-height:44vh; overflow-y:auto; -webkit-overflow-scrolling:touch;
  background:var(--card); border:1px solid var(--line-2); border-radius:var(--r-ctl); box-shadow:0 8px 24px rgba(0,0,0,.16); padding:5px; }
.ondefica-menu[hidden] { display:none; }
.ondefica-item { display:flex; align-items:center; gap:8px; padding:10px 10px; border-radius:9px;
  color:var(--ink); font-size:14px; text-decoration:none; -webkit-tap-highlight-color:transparent; }
.ondefica-item:active { background:var(--tint); color:var(--accent); }
.ondefica-item svg { width:15px; height:15px; flex:none; fill:none; stroke:var(--ink-faint); stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.ondefica-item:active svg { stroke:var(--accent); }
/* Pinned to the top — where it belongs once the keyboard is up (auto-focused on open). */
.searchsheet-form { position:absolute; top:0; left:0; right:0; background:var(--paper);
  padding:calc(12px + env(safe-area-inset-top)) 14px 14px; box-shadow:0 6px 20px rgba(0,0,0,.12); }
/* Search box = the briefing's field treatment, single-line. The in-field mic retired (s62);
   the box is now just the query, so it carries symmetric padding. */
.personwrap .searchsheet-input { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:16px;
  color:var(--ink); background:var(--paper); border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:12px 14px; outline:none; -webkit-appearance:none; appearance:none; }
.personwrap .searchsheet-input:focus { border-color:var(--accent); }
/* Action row (s62): the mic (round, red while recording) beside Buscar, with a live status line
   below. The mic moved OUT of the field — the box is the query, the row is the verbs. */
.searchactions { margin-top:11px; }
.searchactions-row { display:flex; align-items:center; gap:10px; }
/* s70 (his call): the mic disc takes the EXACT height of the primary beside it, per row —
   the buttons keep their sizes. (A stretch+aspect-ratio disc collapsed to an oval in flex;
   a +2px overshoot was tried and reverted — equal is what looks right.) */
.searchactions-row .searchmic { width:43px; height:43px; }               /* beside Buscar / Trazer pra mesa (43) */
.lb-perfect .searchactions-row .searchmic { width:46px; height:46px; }   /* beside Refazer com ajuste (46) */
.searchactions-go { margin-top:0; flex:1; }
.searchmic { flex:none; width:48px; height:48px; border-radius:50%; padding:0; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; -webkit-tap-highlight-color:transparent;
  border:1.5px solid var(--accent); background:var(--paper); color:var(--accent); transition:background .15s,border-color .15s,color .15s; }
.searchmic[hidden] { display:none; }
.searchmic-glyph { width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; transform:translateY(4%); }
.searchmic-spin { display:none; width:22px; height:22px; border-radius:50%; border:2.5px solid var(--tint); border-top-color:var(--accent); animation:vxt-spin .7s linear infinite; }
.searchmic[data-state="rec"] { background:var(--red); border-color:var(--red); color:var(--on-accent); animation:micring 1.4s ease-out infinite; }
@keyframes micring { 0% { box-shadow:0 0 0 0 rgba(192,67,43,.45); } 70%,100% { box-shadow:0 0 0 11px rgba(192,67,43,0); } }
@keyframes vxt-spin { to { transform:rotate(360deg); } }
.searchmic[data-state="busy"] { border-color:var(--line-2); }
/* s72: transcribing an EMPTY field → the disc is a MUTED STATIC mic; the beat is the in-field
   "transcrevendo…" overlay. Dictating MORE into a field that already has text (.mic-appending) →
   the overlay would cover her words, so the DISC spins as the beat instead. One beat, never over text. */
.searchmic[data-state="busy"] .searchmic-glyph { opacity:.35; }
/* s75: dictating MORE → the disc spins. Take the glyph OUT of layout (display:none, not
   opacity:0) so the spinner is the sole flex child and centres — an invisible-but-present
   glyph shoved the spinner ~10px off-centre (the "tiny circle in a corner"). */
.searchmic[data-state="busy"].mic-appending .searchmic-glyph { display:none; }
.searchmic[data-state="busy"].mic-appending .searchmic-spin { display:block; }
/* Status line under the row — RECORDING only now (the transcribing beat moved into the field). */
.searchmic-status { min-height:0; margin-top:8px; font-size:13px; color:var(--ink-soft); }
.searchmic-status > span { display:none; align-items:center; gap:7px; }
.searchactions:has(.searchmic[data-state="rec"]) .s-rec { display:inline-flex; }
.searchmic-status .s-dot { width:8px; height:8px; border-radius:50%; background:var(--red); animation:vxt-pulse 1.2s ease-in-out infinite; }
.searchmic-status .s-time { font-variant-numeric:tabular-nums; color:var(--ink); }
.searchmic-status .s-spin { width:13px; height:13px; border-radius:50%; border:2px solid var(--tint); border-top-color:var(--accent); animation:vxt-spin .7s linear infinite; }
.searchsheet-form .briefsheet-head { margin-bottom:18px; }   /* the field breathes below the title (s50, his call) */
.searchsheet-x { flex:none; border:none; background:none; font-size:26px; line-height:1; color:var(--ink-faint); cursor:pointer; padding:0 2px; -webkit-appearance:none; appearance:none; }
/* Term type-ahead (search-instrument, part 3): the suggested WORD + its per-scope counts. A tap
   fills the field and runs the normal both-scope search. */
.termsuggest[hidden] { display:none; }
.termsuggest { margin-top:10px; max-height:48vh; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.termsuggest-row { display:flex; align-items:baseline; gap:10px; width:100%; text-align:left;
  padding:11px 4px; border:none; border-bottom:0.5px solid var(--line); background:none;
  font-family:var(--sans); cursor:pointer; -webkit-tap-highlight-color:transparent; }
.termsuggest-row:active { background:var(--paper-2); }
.termsuggest-w { flex:1; min-width:0; font-size:15px; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.termsuggest-n { flex:none; font-size:12px; color:var(--ink-faint); }
.placechips[hidden] { display:none; }
.searchsheet-cancel { flex:none; border:none; background:none; color:var(--accent);
  font-family:var(--sans); font-size:15px; font-weight:600; cursor:pointer; }

/* Long-press delete — filling ring + confirm (s6, TravelOps idiom) */
.tilewrap { position:relative; }
.hold-ring { position:absolute; inset:0; display:none; align-items:center; justify-content:center;
  background:rgba(20,16,10,.32); border-radius:inherit; z-index:3; pointer-events:none; }
/* s65 (his call): long-press feedback is just "the image gets darker" + the progress ring —
   there is NO framing box. The scrim inherits the shape it covers, so it darkens edge-to-edge
   with no visible frame on any corner radius (0 on the square prova hero, 16 on tiles, 12 on
   look rows); and the press-in scale is gone — it was the sole cause of the offset "frame". */
/* The scrim lives inside .img on the hold-delete surfaces now (archive, mesa, trash, look
   renders), so it inherits the image's own radius and is clipped to it — no wrap radius, and
   it can never overhang a stretched grid cell. Look grids keep a square wrap for their covers. */
.tilewrap.holding .hold-ring { display:flex; }
/* Throw-to-mesa: an INVISIBLE top-right hot-zone (a coach-mark will introduce it). */
.tomesa { position:absolute; top:0; right:0; width:38px; height:38px; z-index:4;
  border:none; background:none; padding:0; cursor:pointer; -webkit-appearance:none; appearance:none;
  -webkit-tap-highlight-color:transparent; }
/* Picked marker inside the hot-zone: a pin badge that pops when the tile is on the mesa —
   a loud, glanceable point signal on top of the ambient accent frame. Invisible (and
   pointer-transparent, so the tap target is unchanged) until .on-mesa. Instant, no fade,
   to match the frame's "one coherent change" toggle. */
/* ONE svg — disc + glyph in a single viewBox — so both rasterise on the same sub-pixel
   grid. A CSS disc with an inner svg drifted apart on the RIGHT column (the 1fr 1fr grid
   puts it at a fractional device pixel; the s51 glyph-in-disc bug). The shadow is a
   drop-shadow (follows the disc's alpha) and only mounts on the visible pin. */
.tomesa-pin { position:absolute; top:6px; right:6px; width:22px; height:22px; display:block;
  overflow:visible; opacity:0; pointer-events:none; }
/* s77 (his call): the on-mesa badge inverts to a CREAM disc / PURPLE pin — a quieter marker
   that stops the grid shouting purple when several pieces are on the mesa. */
.tomesa-pin circle { fill:var(--paper); stroke:var(--line-2); stroke-width:1; }
.tomesa-pin path { stroke:var(--accent); stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.tilewrap.on-mesa .tomesa-pin { opacity:1; filter:drop-shadow(0 1px 2.5px rgba(20,16,10,.3)); }
/* On the mesa → the pin badge above is the sole picked marker (the accent frame was
   dropped — the pin reads faster at a glance). It persists while the piece is in the pile. */
.hold-ring svg { width:52px; height:52px; transform:rotate(-90deg); }
.hold-ring .trk { fill:none; stroke:rgba(255,255,255,.35); stroke-width:3; }
.hold-ring .prg { fill:none; stroke:#fff; stroke-width:3; stroke-linecap:round; }
.hold-confirm[hidden] { display:none; }
.hold-confirm { position:fixed; inset:0; z-index:98; display:flex; align-items:center; justify-content:center; padding:24px; }   /* above every sheet (s50: a hold can start inside the Localização sheet) */
.hc-backdrop { position:absolute; inset:0; background:rgba(20,16,10,.45); }
.hc-panel { position:relative; width:100%; max-width:360px; background:var(--paper); border-radius:16px;
  padding:22px; box-shadow:0 12px 40px rgba(0,0,0,.28); }
.hc-label { font-size:16px; font-weight:600; text-align:center; margin-bottom:18px; line-height:1.4; }
/* s83: a quiet line under the question — where the piece goes (only when the hold says so) */
.hc-sub { font-size:13px; color:var(--ink-soft); text-align:center; margin:-10px 0 18px; line-height:1.35; }
.hc-sub[hidden] { display:none; }
.hc-actions { display:flex; gap:10px; }
.hc-actions button { flex:1; padding:13px; border-radius:11px; border:none; font-family:var(--sans);
  font-size:14px; font-weight:600; cursor:pointer; }
.hc-cancel { background:var(--paper-2); color:var(--ink); }
.hc-go { background:var(--red); color:#fff; }

/* settings gear + first-run onboarding (session 4) */
.mast .gear { color:var(--ink-faint); text-decoration:none; flex:none; }
.mast .gear svg { width:22px; height:22px; stroke:currentColor; stroke-width:1.4; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.mast .gear:active { color:var(--ink); }
.topbar .gear { color:var(--ink-faint); text-decoration:none; flex:none; }
.topbar .gear svg { width:22px; height:22px; stroke:currentColor; stroke-width:1.4; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.topbar .gear:active { color:var(--ink); }
.onboard { margin:18px 0 4px; border:1px solid var(--line-2); border-radius:10px; padding:18px; background:var(--paper-2); }
.onboard-h { font-family:var(--serif); font-weight:700; font-size:19px; letter-spacing:-.02em; }
.onboard-p { font-size:13px; color:var(--ink-soft); margin-top:6px; line-height:1.5; }
.onboard-row { display:flex; gap:9px; margin-top:16px; }
/* v1.0: the gate asks two things (name + WhatsApp), so it needs labelled fields. */
.onboard-f { display:block; margin-top:15px; }
.onboard-lbl { display:block; font-size:11px; text-transform:uppercase; letter-spacing:.08em; color:var(--ink-faint); margin-bottom:6px; }
.onboard-f > input { width:100%; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:13px 14px; font-family:var(--sans); font-size:16px; color:var(--ink); background:var(--paper); outline:none; }
.onboard-f > input:focus { border-color:var(--ink); }
.onboard-hint { display:block; font-size:12px; color:var(--ink-faint); margin-top:6px; }
.onboard-place { display:block; font-size:12px; color:var(--accent); margin-top:5px; font-weight:600; }
.onboard-err { margin-top:12px; font-size:13px; color:var(--danger, #b3261e); }
.onboard-row button { width:100%; }
.onboard-row input { flex:1; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:13px 14px; font-family:var(--sans); font-size:16px; color:var(--ink); background:var(--paper); outline:none; }
.onboard-row input:focus { border-color:var(--ink); }
.onboard-row button { flex:none; border:none; background:var(--accent); color:var(--on-accent); border-radius:10px; padding:15px 18px; font-family:var(--sans); font-size:16px; font-weight:600; cursor:pointer; }
.onboard-row button:active { background:var(--accent-press); }
.onboard-row button:disabled { opacity:.7; }
.onboardgate { min-height:72vh; display:flex; flex-direction:column; justify-content:center; }
/* The arrival redesign (s64): the gate's vouch ribbon, the gift line, the handle confirm-line. */
.onboard-vouch { display:flex; align-items:center; gap:11px; margin:0 0 15px; padding:10px 12px;
  border-radius:12px; border:1px solid var(--tint-2);
  background:linear-gradient(100deg, var(--tint-2), color-mix(in srgb, var(--dot) 12%, transparent)); }
.onboard-vouch .ov-face { flex:none; width:40px; height:40px; border-radius:50%; background:var(--accent);
  color:var(--on-accent); display:grid; place-items:center; font-weight:700; font-size:16px; }
.onboard-vouch .ov-txt b { display:block; font-size:14px; color:var(--ink); }
.onboard-vouch .ov-txt small { display:block; font-size:11.5px; color:var(--ink-soft); margin-top:1px; line-height:1.35; }
.onboard-gift { display:flex; align-items:flex-start; gap:9px; margin:12px 0 2px; padding:10px 12px;
  border-radius:11px; background:color-mix(in srgb, var(--dot) 12%, transparent); }
.onboard-gift .og-star { flex:none; width:17px; height:17px; margin-top:1px; fill:var(--dot); }
.onboard-gift span { font-size:12.5px; color:var(--ink); line-height:1.4; }
.onboard-gift b { font-weight:700; }
.onboard-handle { margin-top:15px; }
.onboard-handle .ohl-line { font-size:13px; color:var(--ink-soft); display:flex; align-items:center; gap:8px; }
.onboard-handle .ohl-line b { color:var(--accent); font-weight:600; }
.onboard-handle .ohl-edit { margin-left:auto; border:none; background:none; padding:4px 2px;
  font-family:var(--sans); font-size:12.5px; color:var(--accent); cursor:pointer; }
.onboard-handle .ohl-edit:active { color:var(--accent-press); }
.onboard-handle .onboard-f { margin-top:0; }
/* [hidden] must beat the author .onboard-f{display:block} / .ohl-line{display:flex} rules. */
.onboard-handle [hidden] { display:none; }
/* Stepped onboarding wizard (s64): one low-info beat at a time. */
.wiz-top { display:flex; align-items:center; gap:12px; min-height:26px; margin-bottom:12px; }
.wiz-back { border:none; background:none; color:var(--ink-faint); font-size:24px; line-height:1; padding:0 6px 0 0; cursor:pointer; flex:none; }
.wiz-back[hidden] { display:none; }
.wiz-dots { display:flex; gap:6px; align-items:center; }
.wiz-dots i { width:7px; height:7px; border-radius:50%; background:var(--line-2); display:block; transition:width .18s ease, background .18s ease; }
.wiz-dots i.on { background:var(--accent); width:20px; border-radius:5px; }
.wizstep[hidden] { display:none; }
.wiz-eyebrow { font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--accent); margin-bottom:8px; }
/* s67 (his call): the single-field gate buttons carry the requirement as their label —
   muted while unmet, waking to the active plum "Continuar" once the field is filled.
   Same idiom + tokens as the invite prepare button (.invcard-send.is-empty). */
.onboard-row button.is-empty { background:var(--paper-2); border:1px solid var(--line-2); color:var(--ink-soft); font-size:13.5px; }
.onboard-row button.is-empty:active { background:var(--paper-2); }
.wiz-reassure { text-align:center; margin-top:12px; }
.sumcard { background:var(--card); border:1px solid var(--line); border-radius:13px; padding:2px 14px; margin:16px 0 4px; }
.sumrow { display:flex; align-items:center; gap:10px; padding:12px 0; border-top:1px solid var(--line); font-size:14px; color:var(--ink); }
.sumrow:first-child { border-top:none; }
.sumrow .k { color:var(--ink-faint); font-size:11px; text-transform:uppercase; letter-spacing:.06em; width:62px; flex:none; }
.sumrow .v { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sum-ed { margin-left:auto; border:none; background:none; color:var(--accent); font-size:12.5px; cursor:pointer; flex:none; padding:2px; }
.hubcard { position:relative; padding-right:46px; }
.hubcard .cardsub { margin-top:5px; }
.hubcard .chev { position:absolute; right:16px; top:50%; transform:translateY(-50%); width:20px; height:20px;
  stroke:var(--ink-faint); stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }

/* Today — the task layer (s6) */
.taskadd { display:flex; margin:10px 0 16px; }
.taskadd input { flex:1; border:1px solid var(--line-2); border-radius:2px; padding:12px 14px;
  font-family:var(--sans); font-size:16px; color:var(--ink); background:var(--paper-2); outline:none; }
.taskadd input::placeholder { color:var(--ink-faint); }
.taskadd input:focus { border-color:var(--accent); background:var(--paper); }
.tasklist { display:flex; flex-direction:column; margin-bottom:8px; }
.taskrow { display:flex; align-items:center; gap:12px; padding:12px 4px; border-bottom:1px solid var(--line); }
.taskrow form { display:flex; flex:none; margin:0; }
.taskcheck { width:22px; height:22px; border:2px solid var(--line-2); border-radius:50%;
  background:var(--paper); cursor:pointer; flex:none; padding:0; }
.taskcheck:active { background:var(--sand); }
.taskrow.overdue .taskcheck { border-color:var(--red); }
.tasktext { flex:1; min-width:0; font-size:15px; color:var(--ink); }
.taskdue { flex:none; font-size:12px; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.taskdue.late { color:var(--red); font-weight:600; }
.taskdel { flex:none; border:none; background:none; color:var(--ink-faint); font-size:20px; line-height:1;
  cursor:pointer; padding:0 2px; }
.taskdel:active { color:var(--red); }
.taskempty { font-size:13px; color:var(--ink-soft); padding:2px 4px 14px; }

/* color swatches (session 4) — paint-chips on piece + grid */
.swatches { display:flex; flex-wrap:wrap; gap:6px; margin-top:14px; }
.swatches .sw { width:28px; height:28px; border-radius:50%; border:1px solid rgba(0,0,0,.10); }  /* round (s52c) — matches the Cor disc */
.swatches button.sw { -webkit-appearance:none; appearance:none; padding:0; cursor:pointer; }
/* s61 — small READ-ONLY swatches on the rede ficha (the tagged colours, back under the name):
   quiet detail dots, centred, no edit affordance (a rede piece isn't yours). */
.swatches.swatches--sm { justify-content:center; gap:4px; margin-top:9px; }
.swatches.swatches--sm .sw { width:11px; height:11px; }
.swatches .sw.swadd { background:none; border:none; color:var(--ink-faint);
  display:grid; place-items:center; }
.swatches .sw.swadd svg { width:14px; height:14px; display:block; stroke:currentColor;
  stroke-width:1.7; fill:none; stroke-linecap:round; }
/* THE COLOUR SHEET (s53 rebuild): eyedropper is the hero, the search GROUP falls out of
   the picked tone as a live readout, the wheel steps back into a fold, and the auto/manual
   door lives in the footer. Everything colour happens here. */
.cpick[hidden] { display:none; }
.cpick { position:fixed; inset:0; z-index:95; display:flex; align-items:flex-end; }
.cpick-backdrop { position:absolute; inset:0; background:var(--overlay); }
.cpick-panel { position:relative; width:100%; max-width:520px; margin:0 auto; background:var(--card);
  border-radius:var(--r-sheet) var(--r-sheet) 0 0; padding:8px 20px calc(20px + env(safe-area-inset-bottom));
  box-shadow:0 -8px 30px var(--shadow); display:flex; flex-direction:column; gap:13px; }
.cpick-grip { width:38px; height:4px; border-radius:2px; background:var(--line-2); margin:0 auto -2px; }
.cpick-head { display:flex; align-items:center; justify-content:space-between; }
.cpick-title { font-size:17px; font-weight:700; margin:0; color:var(--ink); }
.cpick-x { border:0; background:var(--tint); width:30px; height:30px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.cpick-x svg { width:15px; height:15px; stroke:var(--ink-soft); fill:none; stroke-width:2; }
.cpick-photo-wrap { position:relative; border-radius:var(--r-ctl); overflow:hidden; background:var(--paper-2); line-height:0; }
.cpick-photo-wrap #cpickPhoto { width:100%; display:block; touch-action:none; cursor:crosshair; }
.cpick-loupe { position:absolute; width:76px; height:76px; border-radius:50%; border:2px solid #fff;
  box-shadow:0 2px 10px rgba(0,0,0,.4); pointer-events:none; }
.cpick-loupe[hidden] { display:none; }
.cpick-cap { font-size:12.5px; color:var(--ink-soft); text-align:center; margin:-2px 0 0; }
/* the result: exact hex → the group it lands in */
.cpick-result { display:flex; align-items:center; gap:10px; background:var(--field);
  border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:9px 11px; }
.cpick-chip { width:30px; height:30px; border-radius:8px; flex:none; border:1px solid var(--hair); }
.cpick-result #cpickHex { width:88px; min-width:0; font-family:var(--sans); font-size:16px; font-weight:600;
  letter-spacing:.02em; text-transform:uppercase; border:0; background:none; color:var(--ink); outline:none; padding:0; }
.cpick-arrow { margin-left:auto; color:var(--ink-faint); font-size:15px; }
.cpick-grp { display:inline-flex; align-items:center; gap:6px; background:var(--tint); border-radius:var(--r-pill);
  padding:5px 8px; cursor:pointer; text-decoration:none; color:var(--ink); -webkit-tap-highlight-color:transparent; }
.cpick-gdot { width:15px; height:15px; border-radius:50%; flex:none; border:1px solid var(--hair); background:var(--line-2); }
.cpick-gdot--pattern { background:conic-gradient(from 0deg,#A4271F,#E3B23C,#4E6B3A,#2F5A8C,#6E4A8E,#A4271F); }
.cpick-gname { font-size:13px; font-weight:600; color:var(--ink); }
.cpick-gchev { width:13px; height:13px; stroke:var(--ink-faint); fill:none; stroke-width:2; }
.cpick-teach { font-size:11.5px; line-height:1.4; color:var(--ink-faint); text-align:center; margin:-4px 2px 0; }
.cpick-teach b { color:var(--ink-soft); font-weight:600; }
/* the wheel, folded away by default */
/* the wheel: shown only when there's no photo to eyedrop (s53b) — one picking surface at
   a time, never both. `hidden` is toggled by present() in JS. */
.cpick-wheel { display:flex; flex-direction:column; gap:11px; }
.cpick-wheel[hidden] { display:none; }
.cpick-sv { position:relative; height:148px; border-radius:var(--r-ctl); overflow:hidden; touch-action:none; }
.cpick-sv canvas { width:100%; height:100%; display:block; }
.cpick-sv-dot, .cpick-hue-dot { position:absolute; width:16px; height:16px; border-radius:50%; border:2px solid #fff;
  box-shadow:0 0 0 1px rgba(0,0,0,.35); transform:translate(-50%,-50%); pointer-events:none; }
.cpick-hue { position:relative; height:18px; border-radius:var(--r-pill); touch-action:none;
  background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00); }
.cpick-hue-dot { top:50%; }
/* quiet actions */
.cpick-quiet { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.cpick-quiet:empty { display:none; }
.cpick-removelink { display:inline-flex; align-items:center; gap:6px; border:0; background:none;
  font-family:var(--sans); font-size:12.5px; font-weight:500; color:var(--danger); cursor:pointer; padding:0; }
.cpick-removelink svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.7; }
.cpick-removelink[hidden] { display:none; }
.cpick-autolink { display:inline-flex; align-items:center; gap:6px; border:0; background:none; margin-left:auto;
  font-family:var(--sans); font-size:12.5px; color:var(--ink-soft); cursor:pointer; padding:0; }
.cpick-autolink svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.7; }
.cpick-actions { display:flex; gap:10px; margin-top:2px; }
.cpick-actions button { flex:1; font-family:var(--sans); font-size:14px; font-weight:600; border-radius:var(--r-ctl); padding:13px; cursor:pointer; border:0; }
.cpick-revert { background:var(--field); border:1px solid var(--line-2); color:var(--ink-soft); }
.cpick-go { background:var(--accent); color:var(--on-accent); }
.cpick-go:disabled { opacity:.6; }
.swrow { display:flex; gap:4px; margin-top:6px; }
.swrow .swd { width:11px; height:11px; border-radius:2px; border:1px solid rgba(0,0,0,.10); }

/* ============================================================
   ORÇAMENTO (#7) — owner editor (Galeria) + the topaz deliverable
   ============================================================ */

/* owner editor — bag rows, per-line price, color strip, total */
.palstrip { display:flex; gap:0; margin-top:14px; border-radius:3px; overflow:hidden; width:fit-content; }
.palstrip .palblk { width:26px; height:14px; }
.orclist { display:flex; flex-direction:column; }
.orcrow { display:flex; gap:13px; align-items:flex-start; padding:14px 2px; border-bottom:1px solid var(--line); }
.orcimg { width:54px; aspect-ratio:2/3; flex:none; border-radius:5px; border:1px solid var(--line); overflow:hidden; background:var(--paper-2); display:grid; place-items:center; }
.orcimg img { width:100%; height:100%; object-fit:cover; }
.orcimg svg { width:54%; height:54%; stroke:var(--ink-soft); stroke-width:1.1; fill:none; opacity:.6; }
.orcmain { flex:1; min-width:0; }
.orcname { font-size:14px; font-weight:500; }
a.orcname { display:inline-block; color:inherit; text-decoration:none; }
a.orcname:active { color:var(--accent); }
.orcgo { color:var(--ink-faint); font-weight:400; }
a.orcimg { text-decoration:none; }
.orcsub { font-size:11.5px; color:var(--ink-faint); margin-top:2px; }
.orcprice { display:flex; align-items:center; gap:7px; margin-top:9px; }
.orcprice .cur { font-size:12px; color:var(--ink-faint); }
.orcprice input { width:96px; border:1px solid var(--line-2); border-radius:7px; padding:8px 10px; font-family:var(--sans); font-size:15px; color:var(--ink); background:var(--paper); outline:none; font-variant-numeric:tabular-nums; }
.orcprice input:focus { border-color:var(--ink); }
.orcprice button { flex:none; border:1px solid var(--line-2); background:var(--paper); color:var(--ink-soft); border-radius:7px; padding:8px 11px; font-size:12px; cursor:pointer; }
.orcprice .orcsaved { flex:none; color:var(--ok); font-size:15px; opacity:0; transition:opacity .15s; }
.orcprice .orcsaved.on { opacity:1; }
.orcpickbar { display:flex; gap:8px; align-items:stretch; margin-top:12px; }   /* breathing room under the 'Peças do acervo' summary (s62) */
/* Search field = the app's canon (s35b): a PILL with a magnifying-glass, matching
   .qhome — not the plain rounded-rectangle it was (that read as a generic form input,
   off-canon). Icon baked as a background SVG so both pickers (look + orçamento) get it
   with no markup change; the grey reads faint on light paper, visible on dark. */
.orcpicksearch { flex:1; min-width:0; border:1px solid var(--line-2); border-radius:var(--r-pill);
  padding:11px 16px 11px 40px; font-family:var(--sans); font-size:16px; color:var(--ink);
  background-color:var(--paper); outline:none; -webkit-appearance:none; appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A49CA8' stroke-width='1.7' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:15px center; background-size:16px; }
.orcpicksearch::placeholder { color:var(--ink-faint); }
.orcpicksearch:focus { border-color:var(--accent); }
/* Scope pills (s62, his call): a submitted search shows three — Na mesa · Meu acervo · A
   rede — each with its addable count, so you see where the matches are before a tap. Active
   = plum fill; a 0 count greys out and can't be tapped. Fixed labels + capped counts (99+)
   keep three on one line at 375pt. */
.orcpillrow { display:flex; gap:7px; margin-top:12px; }
.orcpill { font-size:12.5px; font-weight:600; padding:6px 12px; border-radius:var(--r-pill);
  background:var(--paper-2); color:var(--ink-soft); border:1px solid transparent; white-space:nowrap;
  font-family:inherit; cursor:pointer; -webkit-appearance:none; appearance:none; }
.orcpill .orcpill-c { font-weight:700; }
.orcpill.on { background:var(--accent); color:var(--on-accent); }
.orcpill.off { background:transparent; color:var(--ink-faint); border:1px dashed var(--line-2); cursor:default; }
/* Source-tier label (na mesa / seu acervo / na rede): a quiet marker with air above,
   not a body-text paragraph crammed against the field (s35b, S/N #3). */
.picktier { font-size:11px; letter-spacing:.1em; text-transform:uppercase; font-weight:500;
  color:var(--ink-faint); margin:18px 2px 0; }
/* Capture-in-orçamento: snap a not-yet-logged piece straight into the quote. */
.orcpickcam { position:relative; flex:none; display:grid; place-items:center; width:46px; border:1px solid var(--accent);
  border-radius:var(--r-ctl); background:color-mix(in srgb, var(--accent) 6%, var(--paper)); color:var(--accent); cursor:pointer;
  -webkit-tap-highlight-color:transparent; }
.orcpickcam svg { width:22px; height:22px; stroke:currentColor; stroke-width:1.6; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.orcpickcam input { position:absolute; inset:0; width:100%; height:100%; opacity:0; margin:0; padding:0; border:0; cursor:pointer; font-size:16px; }
.orcpickcamnote { display:block; font-size:12.5px; color:var(--accent); margin-top:8px; }
.orcpickcamnote[hidden] { display:none; }
.orcpickresults { margin-top:2px; }
/* s77 (his call): align-items:start so a sizeless cell isn't stretched to a captioned
   neighbour's height — no phantom empty tab under it (mirrors the acervo grid, 4d5d020). */
.orcpickgrid { display:grid; grid-template-columns:1fr 1fr 1fr; gap:6px; margin-top:10px; align-items:start; }
.orcpickcell { position:relative; }
.orcpickcell.added { opacity:.62; }
.orcpickcell.added::after { content:'✓'; position:absolute; top:4px; right:4px; width:20px; height:20px;
  display:grid; place-items:center; border-radius:50%; background:var(--accent); color:var(--on-accent);
  font-size:12px; font-weight:700; }
.orcpickcell { border:1px solid var(--line); border-radius:var(--r-ctl); background:var(--paper); padding:0; cursor:pointer; display:flex; flex-direction:column; gap:0; overflow:hidden; }
.orcpickcell img, .orcpickcell .ph { width:100%; aspect-ratio:2/3; object-fit:cover; background:var(--paper-2); display:block; }
.orcpickcell small { font-size:10.5px; color:var(--ink-faint); padding:6px 6px 7px; text-transform:none; letter-spacing:.01em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.orcpickcell:active { border-color:var(--accent); }
.orcpickcell:disabled { opacity:.55; }
.orcpickcell .netowner { color:var(--accent); }
/* The look picker's mode chips ride buttons, not links (the workbench, s27). */
.orcpick .pickback, .orcpick button.netflip { -webkit-appearance:none; appearance:none; cursor:pointer; }
.orcpick .pickback { margin:14px 0 4px; }
.orcpick button.netflip { border:none; background:none; padding:0; font-size:14px; color:var(--accent); font-family:inherit; }
.orcrow .bx button { flex:none; width:26px; height:26px; border:1px solid var(--line-2); background:var(--paper); color:var(--ink-faint); border-radius:5px; font-size:15px; line-height:1; cursor:pointer; }
/* charge rows carry no image — label left, price right on one line */
.orcrow.charge { align-items:center; }
.orcrow.charge .orcmain { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.orcrow.charge .orcname { font-size:14px; font-weight:500; }
.orcrow.charge .orcprice { margin-top:0; }
/* add-a-charge: label spans the row, then price + button on one line beneath */
.chargeadd { display:flex; flex-direction:column; gap:8px; margin-top:14px; }
.chargeadd input[name=label] { width:100%; border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:11px 12px; font-family:var(--sans); font-size:15px; color:var(--ink); background:var(--paper);
  outline:none; -webkit-appearance:none; appearance:none; }
.chargeadd input[name=label]:focus { border-color:var(--accent); }
.chargeadd-row { display:flex; gap:8px; align-items:stretch; }
.chargeadd-price { flex:1; min-width:0; display:flex; align-items:center; gap:6px; border:1px solid var(--line-2);
  border-radius:var(--r-ctl); padding:0 12px; background:var(--paper); }
.chargeadd-price .cur { font-size:12px; color:var(--ink-faint); }
.chargeadd-price input { flex:1; min-width:0; border:none; background:transparent; padding:11px 0;
  font-family:var(--sans); font-size:15px; color:var(--ink); outline:none; font-variant-numeric:tabular-nums; }
.chargeadd-row .btn { flex:none; width:auto; }
.orctotals { margin-top:14px; }
.orctotal { display:flex; justify-content:space-between; align-items:baseline; padding:16px 2px 2px; }
.orctotal span:first-child { font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint); }
.orctotal .v { font-family:var(--serif); font-weight:700; font-size:20px; letter-spacing:-.02em; }
/* subtotal / desconto / sinal rows (#26) — quiet, inline-editable */
.orctline { display:flex; justify-content:space-between; align-items:center; padding:7px 2px;
  font-size:13.5px; color:var(--ink-soft); border-bottom:1px solid var(--line); margin:0; }
.orctline .tnum { font-variant-numeric:tabular-nums; }
.orcedit .orcedit-v { display:inline-flex; align-items:center; gap:4px; color:var(--ink);
  font-variant-numeric:tabular-nums; }
.orcedit input { width:70px; border:1px solid var(--line-2); border-radius:6px; padding:5px 8px;
  font-family:var(--sans); font-size:14px; text-align:right; background:var(--paper); outline:none;
  font-variant-numeric:tabular-nums; }
.orcedit input:focus { border-color:var(--accent); }
.orcedit select { border:1px solid var(--line-2); border-radius:6px; padding:5px 8px; font-size:14px;
  background:var(--paper); color:var(--ink); -webkit-appearance:none; appearance:none; }
/* NFS-e / recibo handoff (#26) — copy-ready fiscal blocks for the city portal */
.fiscalout { margin-top:8px; }
.fiscalout > summary { font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-faint);
  cursor:pointer; padding:8px 2px; list-style:none; }
.fiscalout > summary::-webkit-details-marker { display:none; }
.fiscalout > summary::before { content:"＋ "; color:var(--ink-faint); }
.fiscalout[open] > summary::before { content:"－ "; }
.fiscalcard { border:1px solid var(--line-2); border-radius:var(--r-card); padding:14px; margin-top:12px; background:var(--paper-2); }
.fiscalcard-h { display:flex; justify-content:space-between; align-items:baseline; gap:10px;
  font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--accent); font-weight:700; }
.fiscalcard-h span { font-family:var(--serif); letter-spacing:0; text-transform:none; color:var(--ink);
  font-size:15px; font-variant-numeric:tabular-nums; }
.fiscaltext { margin:11px 0 12px; font-family:ui-monospace,Menlo,monospace; font-size:11.5px; line-height:1.55;
  white-space:pre-wrap; word-break:break-word; color:var(--ink-soft); }
.fiscalcard .btn { width:100%; }
/* orçamento lifecycle bar (#25) — number · status badge · validity */
.orcstatusbar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:6px 2px 14px; }
.orcnum { font-size:12px; font-weight:700; color:var(--ink-soft); font-variant-numeric:tabular-nums; letter-spacing:.03em; }
.orcstatus { font-size:11px; font-weight:600; padding:3px 11px; border-radius:20px; background:var(--paper-2); color:var(--ink-soft); }
.orcstatus.s-aprovado, .orcstatus.s-convertido { background:var(--chip-ok-bg); color:var(--chip-ok-ink); }
.orcstatus.s-ajustes { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.orcstatus.s-expirado { background:var(--chip-alert-bg); color:var(--chip-alert-ink); }
.orcstatus.s-visto, .orcstatus.s-enviado { background:color-mix(in srgb, var(--accent) 12%, var(--paper)); color:var(--accent); }
.orcvalid { font-size:11.5px; color:var(--ink-faint); }
.orcvalid.exp { color:var(--brick); font-weight:600; }
.orcvaliddays { margin-left:auto; }
.orcvaliddays select { font-size:11.5px; color:var(--ink-soft); border:1px solid var(--line-2);
  border-radius:7px; padding:4px 8px; background:var(--paper); -webkit-appearance:none; appearance:none; }
.sharebox { display:flex; flex-direction:column; gap:11px; }
.shareurl { width:100%; border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 13px; font-family:var(--sans); font-size:13px; color:var(--ink-soft); background:var(--paper-2); outline:none; }
.orcmeta { display:flex; flex-direction:column; gap:13px; padding-top:14px; }
.orcmeta label { display:flex; flex-direction:column; gap:6px; font-size:11px; letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); }
.orcmeta input, .orcmeta textarea { border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 13px; font-family:var(--sans); font-size:16px; color:var(--ink); background:var(--paper); outline:none; letter-spacing:normal; text-transform:none; }
.orcmeta input:focus, .orcmeta textarea:focus { border-color:var(--ink); }

/* in-app PDF viewer — the standalone app has no browser chrome, so the PDF gets
   a page of its own: a way back, share/download, and pages as fit-width images.
   Pan/zoom is CONTAINED in .pdfzoom (transform on .pdfcanvas) — viewport zoom
   would scale the app chrome, so the app-wide maximum-scale=1 stands. */
.pdfactions { display:flex; gap:10px; padding:14px 0 4px; }
.pdfactions a.pdfshare { flex:none; width:auto; display:inline-flex; align-items:center; justify-content:center; padding:0 22px; }
.pdfshare svg { width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; display:block; }
.pdfactions .btn { flex:1; text-align:center; text-decoration:none; }
/* base (s49): the share ALONE is the page's one verb — it wears the primary dress, full width,
   same height as its Studio sibling row (the ghost square alone read as an empty bar). */
.pdfactions a.pdfshare:only-child { flex:1; width:100%; min-height:48px; padding:12px 22px;
  background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.pdfactions a.pdfshare:only-child:active { background:var(--accent-press); }
.pdfshare-lbl { display:none; }
.pdfactions a.pdfshare:only-child { gap:9px; font-size:14.5px; font-weight:600; }
.pdfactions a.pdfshare:only-child .pdfshare-lbl { display:inline; }   /* the word rides only when the glyph is alone */
/* the send moment stacks (s39): primary send, the link row, then the quiet pair */
.pdfactions--send { flex-direction:column; align-items:stretch; gap:8px; }
.pdfactions--send .siglink { margin:0; }
.pdfzoom { position:relative; overflow:hidden; margin-top:12px; border-radius:var(--r-ctl);
  border:1px solid var(--line); background:var(--paper-2);
  height:calc(100dvh - 300px); min-height:340px; touch-action:none; cursor:grab; }
.pdfzoom:active { cursor:grabbing; }
.pdfcanvas { position:absolute; top:0; left:0; width:100%;
  transform-origin:0 0; will-change:transform;
  display:flex; flex-direction:column; gap:12px; padding:10px; }
.pdfpage { display:block; width:100%; height:auto; border:1px solid var(--line);
  border-radius:4px; background:#fff; -webkit-user-select:none; user-select:none;
  box-shadow:0 2px 6px rgba(63,55,45,.06), 0 10px 22px -12px rgba(63,55,45,.14); }
/* Loading skeleton (s39): while a page PNG is in flight the img reserves its A4
   footprint and shimmers — the build takes real seconds on first view, and a blank
   void read as broken. aspect-ratio releases once the bitmap paints (height:auto
   wins), and the shimmer is background — fully covered by the opaque page. */
.pdfpage { aspect-ratio: auto 210 / 297;
  background:linear-gradient(100deg, #fff 40%, #F1EAE0 50%, #fff 60%) #fff;
  background-size:200% 100%; animation:pdfshimmer 1.2s linear infinite; }
@keyframes pdfshimmer { from { background-position:120% 0; } to { background-position:-80% 0; } }
/* pinch affordance — a corner glyph, not a sentence; fades once you start zooming */
.pdfpinch { position:absolute; right:10px; bottom:10px; width:30px; height:30px;
  display:grid; place-items:center; border-radius:50%; pointer-events:none;
  background:rgba(40,28,48,.62); color:#fff; transition:opacity .2s; }
.pdfpinch svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.pdfzoom.zoomed .pdfpinch { opacity:0; }
.pdfnote { margin-top:10px; text-align:center; }

/* the topaz deliverable — fixed, serious, owner-skin-proof. Its own tokens. */
.orc {
  --t-paper:#FBF6EE; --t-ink:#1C2522; --t-faint:#6B7570;
  --t-teal:#2F6F62; --t-sand:#F1DCC2; --t-line:#E4D7C5;
  --t-sans:'Inter',system-ui,sans-serif;
  max-width:560px; margin:0 auto; padding:0 22px 90px; min-height:100vh;
  background:var(--t-paper); color:var(--t-ink); font-family:var(--t-sans);
}
.orc-head { padding:50px 0 8px; }
.orc-studio { font-family:var(--t-sans); font-size:12px; font-weight:700; letter-spacing:.18em;
  text-transform:uppercase; color:var(--t-teal); display:flex; justify-content:space-between;
  align-items:baseline; gap:12px; flex-wrap:wrap; }
.orc-meta { font-weight:600; letter-spacing:.04em; color:var(--t-faint); text-transform:none;
  font-variant-numeric:tabular-nums; }
.orc-expired { margin:14px 0 0; background:#F2DCD5; color:#A2402C; border-radius:10px;
  padding:11px 15px; font-size:13.5px; font-weight:600; }
.orc-head h1 { font-family:var(--t-sans); font-weight:800; font-size:40px; line-height:1.02;
  letter-spacing:-.03em; margin:14px 0 0; color:var(--t-ink); }
.orc-strip { display:flex; gap:0; margin:22px 0 0; border-radius:4px; overflow:hidden; width:fit-content;
  box-shadow:0 1px 0 rgba(0,0,0,.04); }
.orc-strip span { width:34px; height:18px; }
.orc-for { font-size:14px; color:var(--t-faint); margin-top:22px; }
.orc-for b { color:var(--t-ink); font-weight:600; }
.orc-items { margin-top:30px; border-top:2px solid var(--t-ink); }
.orc-item { display:flex; gap:16px; align-items:center; padding:16px 0; border-bottom:1px solid var(--t-line); }
.orc-thumb { width:72px; aspect-ratio:2/3; flex:none; border-radius:6px; overflow:hidden;
  background:var(--t-sand); display:grid; place-items:center; }
.orc-thumb img { width:100%; height:100%; object-fit:cover; }
.orc-noimg svg { width:42%; height:42%; stroke:var(--t-teal); stroke-width:1; fill:none; opacity:.5; }
.orc-body { flex:1; min-width:0; }
.orc-name { font-size:17px; font-weight:700; letter-spacing:-.01em; }
.orc-sub { font-size:12.5px; color:var(--t-faint); margin-top:3px; }
.orc-line-price { font-weight:700; font-size:15px; font-variant-numeric:tabular-nums; color:var(--t-ink); white-space:nowrap; }
/* The look line gets a bigger stage (its image is a dressed person, not a garment),
   and the spread below names each piece of the outfit. */
.orc-item-look { border-bottom:none; padding-bottom:10px; }
.orc-item-look .orc-thumb { width:104px; }
.orc-spread { display:flex; gap:10px; overflow-x:auto; padding:0 0 16px; margin:0;
  border-bottom:1px solid var(--t-line); -webkit-overflow-scrolling:touch; }
.orc-spread-pc { flex:none; width:64px; margin:0; }
.orc-spread-pc img, .orc-spread-pc .orc-noimg { width:64px; aspect-ratio:2/3; object-fit:cover;
  border-radius:5px; background:var(--t-sand); display:grid; place-items:center; }
.orc-spread-pc figcaption { font-size:10.5px; line-height:1.25; color:var(--t-faint); margin-top:4px;
  overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.orc-total { display:flex; justify-content:space-between; align-items:baseline; margin-top:20px;
  padding-top:16px; border-top:2px solid var(--t-teal); }
.orc-total span:first-child { font-size:12px; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--t-faint); }
.orc-total-v { font-weight:800; font-size:28px; letter-spacing:-.03em; color:var(--t-teal); font-variant-numeric:tabular-nums; }
.orc-subline { display:flex; justify-content:space-between; font-size:13.5px; color:var(--t-faint);
  padding:5px 0; font-variant-numeric:tabular-nums; }
.orc-subline.dep { margin-top:8px; color:var(--t-ink); font-weight:600; }
.orc-block { margin-top:32px; background:#fff; border:1px solid var(--t-line); border-radius:10px; padding:18px 20px; }
.orc-block.muted { background:transparent; border:none; padding:18px 0 0; }
.orc-block-h { font-size:11px; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--t-teal); }
.orc-block p { font-size:13.5px; line-height:1.6; color:var(--t-faint); margin-top:9px; }
.orc-charge { display:flex; justify-content:space-between; gap:12px; padding:9px 0; font-size:14px;
  color:var(--t-ink); border-bottom:1px solid var(--t-line); }
.orc-charge:last-child { border-bottom:none; padding-bottom:0; }
.orc-charge:first-of-type { padding-top:12px; }
.orc-charge-v { font-variant-numeric:tabular-nums; color:var(--t-faint); }
.orc-pix .orc-pix-code { margin-top:12px; font-family:ui-monospace,Menlo,monospace; font-size:11px;
  line-height:1.5; word-break:break-all; color:var(--t-faint); background:var(--t-wash,#f5f3ee);
  border:1px solid var(--t-line); border-radius:var(--r-ctl); padding:11px 12px; max-height:78px; overflow:auto; }
.orc-pix .orc-pix-copy { display:block; width:100%; margin-top:12px; background:var(--t-teal); color:#fff;
  border:none; font-weight:700; font-size:14px; padding:13px; border-radius:10px; letter-spacing:.01em; }
.orc-pix .orc-pix-copy:active { background:#27594f; }
.orc-pdf { display:block; text-align:center; margin-top:34px; background:var(--t-teal); color:#fff;
  text-decoration:none; font-weight:700; font-size:15px; padding:16px; border-radius:11px; letter-spacing:.01em; }
.orc-pdf:active { background:#27594f; }
.orc-foot { text-align:center; margin-top:40px; font-size:11px; font-weight:700; letter-spacing:.2em;
  text-transform:uppercase; color:var(--t-faint); }

/* client decision (#3) — approve / request changes, in the topaz look */
.orc-decide { margin-top:16px; display:flex; flex-direction:column; gap:10px; }
/* The stale-page bounce (s47f): the owner edited while this render sat open —
   say so plainly before the client re-approves. */
.orc-changed-note { font-size:13.5px; font-weight:600; color:var(--chip-warn-ink);
  background:var(--chip-warn-bg); border-radius:var(--r-ctl); padding:10px 14px; }
.orc-approve { background:var(--t-teal); color:#fff; border:none; font-family:var(--t-sans);
  font-weight:700; font-size:15px; padding:16px; border-radius:11px; cursor:pointer; }
.orc-approve:active { background:#27594f; }
.orc-changes { background:transparent; color:var(--t-teal); border:1px solid var(--t-line);
  font-family:var(--t-sans); font-weight:600; font-size:14px; padding:13px; border-radius:11px; cursor:pointer; }
.orc-changesform { display:flex; flex-direction:column; gap:9px; margin-top:2px; }
.orc-changesform[hidden] { display:none; }
.orc-changesform textarea { border:1px solid var(--t-line); border-radius:10px; padding:12px 14px;
  font-family:var(--t-sans); font-size:15px; color:var(--t-ink); background:#fff; resize:none; outline:none; }
.orc-changesform button { background:var(--t-ink); color:#fff; border:none; font-family:var(--t-sans);
  font-weight:700; font-size:14px; padding:13px; border-radius:11px; cursor:pointer; }
.orc-decided { margin-top:20px; display:flex; align-items:center; gap:13px; padding:16px 18px;
  border-radius:11px; background:#fff; border:1px solid var(--t-line); }
.orc-decided.ok { border-color:var(--t-teal); }
.orc-decided svg { flex:none; width:26px; height:26px; fill:none; stroke:var(--t-teal); stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round; }
.orc-decided b { display:block; font-size:15px; font-weight:700; color:var(--t-ink); }
.orc-decided span { display:block; font-size:12.5px; color:var(--t-faint); margin-top:2px; }

/* the "add to orçamento" pickers on piece + look detail */
.toorc summary { cursor:pointer; }
.toorc-form { display:flex; flex-direction:column; gap:10px; padding-top:13px; }
.toorc-form select, .toorc-form input { border:1px solid var(--line-2); border-radius:var(--r-ctl); padding:12px 13px; font-family:var(--sans); font-size:16px; color:var(--ink); background:var(--paper); outline:none; }
.toorc-form select:focus, .toorc-form input:focus { border-color:var(--ink); }
.toorc-form button { border:none; background:var(--accent); color:var(--on-accent); border-radius:var(--r-ctl); padding:13px; font-family:var(--sans); font-size:14px; font-weight:500; cursor:pointer; }

/* ============================================================
   WORK CARDS — the two kinds of job (TravelOps pattern). One card
   shape, two faces: Produção (portfolio — palette + looks) and
   Locação (operations — client + return clock + balance).
   ============================================================ */
.cardlist { display:flex; flex-direction:column; gap:16px; margin-top:12px; }
/* hold-to-delete on trabalho cards — light card, so an accent ring on a soft scrim
   (the piece tiles use a white ring on the photo; that'd vanish on paper) */
.wcardwrap { position:relative; }
.wcardwrap.holding .hold-ring { display:flex; background:rgba(40,28,48,.06); border-radius:18px; }
.wcardwrap .hold-ring .trk { stroke:rgba(60,50,35,.18); }
.wcardwrap .hold-ring .prg { stroke:var(--accent); }
/* Kind-colored spine RETIRED (s41 S/N): a 5px edge encoded the TYPE (produção/orçamento/
   locação/empréstimo) — a second colour axis that duplicated the eyebrow text and had no
   legend, while STATUS (what you scan for) got only a pill. Colour now carries ONE axis:
   status/urgency, via the section header + the late-card tint. Kind is a muted eyebrow. */
/* D-card pulse (s23b, de-noised): one quiet caption + a thin looks-montados bar */
.cardpulse { margin-top:15px; }
.cardpulse-cap { font-size:12.5px; color:var(--ink-soft); margin-bottom:7px; }
.cardpulse-cap b { color:var(--ink); font-weight:700; }
.cardpulse-bar { height:4px; border-radius:3px; background:var(--paper-2); overflow:hidden; }
.cardpulse-bar i { display:block; height:100%; border-radius:3px; background:var(--accent); }
.wcard { display:block; text-decoration:none; color:var(--ink); background:var(--card);
  border:1px solid var(--line); border-radius:18px; padding:21px 20px;
  box-shadow:0 1px 2px rgba(60,50,35,.04), 0 12px 26px -16px rgba(60,50,35,.16);
  transition:box-shadow .15s, transform .12s; }
.wcard:active { transform:translateY(1px); box-shadow:0 1px 2px rgba(60,50,35,.05); }
.cardpalette { display:flex; border-radius:4px; overflow:hidden; width:fit-content; margin-bottom:14px; }
.cardpalette span { width:26px; height:15px; }
.cardtop { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:12px; }
.cardeyebrow { font-size:11.5px; letter-spacing:.14em; color:var(--ink-faint); }
/* LATE is the one exception a tint earns (s41 stress test): a rare, high-stakes state
   that must break out of its group, so it gets the alert wash + a red edge — colour
   intensity reserved for what actually needs to shout, not spent on every card. */
.wcard.late { background:var(--chip-alert-bg); border-color:color-mix(in srgb, var(--danger) 28%, var(--line)); border-left:3px solid var(--danger); }
.cardstage { flex:none; font-size:11px; padding:3px 10px; border-radius:20px;
  background:var(--paper-2); color:var(--ink-soft); white-space:nowrap; }
.cardstage.ok { background:var(--chip-ok-bg); color:var(--chip-ok-ink); }
.cardstage.warn { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.cardstage.alert { background:var(--chip-alert-bg); color:var(--chip-alert-ink); }
.cardstage.muted { background:var(--paper-2); color:var(--ink-faint); }
.cardtitle { font-family:var(--serif); font-weight:700; font-size:24px; letter-spacing:-.025em;
  line-height:1.03; color:var(--ink); }
.cardtitle.sm { font-size:20px; letter-spacing:-.015em; }
.cardsub { font-size:13px; color:var(--ink-soft); margin-top:5px; }
.cardep { font-size:13px; font-weight:600; color:var(--accent); margin-top:3px; }
/* Borrow lifecycle verb (devolver / cancelar pedido): a quiet pill over the card's
   bottom-right corner — a sibling of the anchor, so its tap never triggers the card
   link. Not the long-press delete idiom (these are state transitions, not deletes). */
.cardact { position:absolute; right:16px; bottom:14px; z-index:2; }
.cardact button { font:inherit; font-size:12.5px; font-weight:600; color:var(--accent);
  background:var(--paper); border:1px solid var(--line-2); border-radius:var(--r-ctl);
  padding:6px 13px; cursor:pointer; }
.cardact button:active { background:var(--paper-2); }
/* Proposta card (s33): a sent look on Trabalhos. Reserve the bottom-right so the
   Virar locação pill (.cardact) never sits on the money line; the × clears the
   receipt from the top-right, clear of the eyebrow. */
.wcard.propostacard { padding-bottom:46px; }
.pcardx { position:absolute; right:9px; top:9px; z-index:3; }
.pcardx .taskdel { padding:2px 6px; }
/* Named-crossing tail under Propostas — reach a look to graduate (never sent / faded). */
.engtail { display:inline-block; margin:-2px 4px 12px; font-size:13px;
  color:var(--accent); text-decoration:none; }
.engtail:active { opacity:.6; }
/* Virar locação — the look page's one commercial verb (s33). Topbar-native TEXT LINK
   (s35b, S/N): a bordered card-chip read as a heavy transplant beside the airy back
   link; matched to the back link's weight + scale, the header goes even. */
/* The lookbook door (s44): a closed-book glyph + a tiny "lookbook" word, pinned to the
   top-right of the look's title line — it MAKES the lookbook (see-before-commit), where
   the 'Virar locação' verb then lives. The title takes the room; the book never crowds it. */
.tt-titlerow { display:flex; align-items:flex-start; gap:10px; }
.tt-titlerow .qtitle-form { flex:1; min-width:0; }
.lookbookbtn { flex:none; display:inline-flex; align-items:center; gap:5px; margin-top:5px;
  padding:8px 6px; font-size:11px; letter-spacing:.04em; color:var(--accent);
  text-decoration:none; background:none; -webkit-tap-highlight-color:transparent; }
.lookbookbtn svg { width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.lookbookbtn:active { opacity:.6; }
.cardmeta { display:flex; align-items:center; gap:7px; font-size:12.5px; color:var(--ink-soft); margin-top:11px; }
/* Front door — Novo trabalho, the intake CTA at the top of the list */
.newtrabalho { display:flex; align-items:center; gap:13px; margin:6px 0 18px; padding:15px 16px;
  border-radius:14px; text-decoration:none; color:var(--ink);
  background:color-mix(in srgb, var(--accent) 9%, var(--paper)); border:1px solid color-mix(in srgb, var(--accent) 22%, transparent); }
.newtrabalho:active { background:color-mix(in srgb, var(--accent) 15%, var(--paper)); }
.newtrabalho-ic { flex:none; width:40px; height:40px; border-radius:50%; background:var(--accent);
  display:grid; place-items:center; }
.newtrabalho-ic svg { width:22px; height:22px; stroke:var(--on-accent); stroke-width:2; fill:none; stroke-linecap:round; }
.newtrabalho b { display:block; font-size:15px; }
.newtrabalho small { display:block; font-size:12px; color:var(--ink-soft); margin-top:2px; }
.cardmeta svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.5; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:none; }
.cardmoney { font-size:13px; color:var(--ink-soft); margin-top:12px; font-variant-numeric:tabular-nums; }
.cardmoney .open { color:var(--brick); }

/* Produção face — stage pill tints */
.pcard.stage-ativa .cardstage { background:var(--chip-ok-bg); color:var(--chip-ok-ink); }
.pcard.stage-planejamento .cardstage { background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.pcard.stage-rascunho .cardstage { background:var(--paper-2); color:var(--ink-faint); }
.pcard.stage-encerrada { opacity:.78; }
.pcard.stage-encerrada .cardstage { background:var(--paper-2); color:var(--ink-faint); }

/* Locação face — operations: piece thumbnails + the return clock */
.lcard.state-closed, .lcard.state-cancelled { opacity:.74; }
.lthumbs { display:flex; align-items:center; gap:6px; margin-top:12px; }
.lthumb { width:34px; height:42px; border-radius:4px; overflow:hidden; background:var(--paper-2);
  border:1px solid var(--line); flex:none; }
.lthumb img { width:100%; height:100%; object-fit:cover; display:block; }
.lmore { font-size:12px; color:var(--ink-faint); font-variant-numeric:tabular-nums; }
/* Pieces-lead cards (s42+): the strip rides above the title, a touch larger — it's
   now the card's identity, not a footnote. */
.lthumbs.lead { margin-top:0; margin-bottom:13px; }
.lthumbs.lead .lthumb { width:40px; height:50px; }
.cardmeta.late { color:var(--red); }
/* Return-clock urgency ramp (s42+), redundant with the word so it survives grayscale:
   atrasada=red · hoje=amber · amanhã=a faint warm (dimmer than hoje) · further out=neutral. */
.cardmeta.alert { color:var(--red); }
.cardmeta.warn { color:var(--warn); }
.cardmeta.soon { color:color-mix(in srgb, var(--warn) 55%, var(--ink-soft)); }

/* orçamento → job funnel: two graduation actions side by side */
.gradrow { display:flex; gap:10px; }
.gradrow form { flex:1; }
.gradrow .btn { width:100%; }

/* ============================================================
   INLINE EDIT (TravelOps receipt-sheet idiom) — the detail page IS
   the edit page. Fields read as plain facts; quiet until tapped, then
   a soft affordance appears. Auto-saves on blur (see app.js).
   ============================================================ */
.inline-edit { display:flex; flex-direction:column; margin-top:4px; }
.inline-saved { align-self:flex-start; font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ok); opacity:0; transition:opacity .22s; margin-bottom:2px; height:13px; pointer-events:none; }
.inline-saved.on { opacity:1; }
.inline-row { display:flex; gap:14px; }
.inline-row .inline-field { flex:1; min-width:0; }
.inline-field { display:flex; flex-direction:column; gap:3px; padding:7px 0; }
.inline-field label { font-size:10px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-faint); }
.inline-field input, .inline-field select, .inline-field textarea {
  width:100%; border:1px solid transparent; border-radius:var(--r-ctl); background:transparent;
  padding:6px 9px; font-family:var(--sans); font-size:16px; line-height:1.35; color:var(--ink);
  -webkit-appearance:none; appearance:none; resize:none; }
.inline-field input:focus, .inline-field select:focus, .inline-field textarea:focus {
  border-color:rgba(47,111,98,.45); background:var(--paper-2); outline:none; }
.inline-field input::placeholder, .inline-field textarea::placeholder { color:var(--ink-faint); }
.inline-field.inline-title { padding-top:2px; gap:5px; }
.inline-field.inline-title input { font-family:var(--serif); font-weight:700; font-size:27px;
  letter-spacing:-.025em; line-height:1.04; padding:3px 9px; }
/* the big serif title reads as static ink, so a pencil says "tappable" — it sits
   past the text, fades on focus (you're already editing). */
.titlewrap { position:relative; display:block; }
.titlewrap input { width:100%; padding-right:34px; }
.titlepen { position:absolute; right:8px; top:50%; transform:translateY(-50%);
  width:16px; height:16px; fill:none; stroke:var(--ink-faint); stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; pointer-events:none; transition:opacity .15s; }
.titlewrap input:focus + .titlepen { opacity:0; }

/* ============================================================
   ACERVO OVERVIEW — the collection as a category index (counts +
   colour signature + subcategory tree). The number is the payload;
   the palette carries the taste. Front door once the archive is big.
   ============================================================ */
.ovlist { display:flex; flex-direction:column; gap:15px; margin-top:12px; }
.trashlink { display:inline-flex; align-items:center; gap:7px; margin:22px 2px 6px; font-size:13px; color:var(--ink-soft); text-decoration:none; }
.trashlink svg { width:16px; height:16px; stroke:currentColor; stroke-width:1.5; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.trashlink:active { color:var(--accent); }
/* category cards — full-size TravelOps card: a vertical colour-distribution block on
   the left, serif name + big serif count, and a tap-to-toggle rede globe on the right. */
.ccard { position:relative; width:100%; background:#F7F6F3; border-radius:15px;
  box-shadow:0 2px 6px rgba(63,55,45,.05),
    0 12px 26px -10px rgba(63,55,45,.16), 0 26px 50px -30px rgba(63,55,45,.2);
  transition:box-shadow .15s, transform .12s; }
/* Press feedback ONLY when the drill link is pressed — tapping the globe (a sibling
   button) must not nudge the whole card (the residual on-device jitter). */
.ccard:has(.cc-hit:active) { transform:translateY(1px); box-shadow:0 1px 3px rgba(63,55,45,.06); }
.cc-hit { display:grid; grid-template-columns:44px 1fr auto; gap:15px; align-items:center;
  text-decoration:none; padding:14px 74px 14px 14px; }
.cc-block { display:flex; flex-direction:column; height:62px; border-radius:var(--r-ctl); overflow:hidden;
  background:var(--line-2); }
.cc-block span { display:block; min-height:2px; }
.cc-name { font-family:var(--serif); font-weight:400; font-size:23px; line-height:1.04;
  letter-spacing:-.01em; color:#453E36; overflow-wrap:anywhere; }
.cc-num { font-family:var(--serif); font-weight:400; font-size:38px; line-height:.8;
  letter-spacing:-.02em; color:#453E36; font-variant-numeric:tabular-nums; }
/* 3+ digit tallies (100+) shrink so they fit beside the name — small counts keep the
   big-number drama, big ones stop crowding the category name. */
.cc-num.wide { font-size:27px; letter-spacing:-.01em; }
.cc-globe { position:absolute; top:0; right:0; bottom:0; width:66px; display:flex;
  flex-direction:column; align-items:center; justify-content:center; padding:0;
  border:none; background:none; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.cc-globe svg { width:22px; height:22px; fill:none; stroke:var(--ink-faint); stroke-width:1.5; }
.cc-globe:active svg { transform:scale(.9); }
/* The caption is anchored just BELOW the centred icon and grows downward — pulled out
   of the flex flow so toggling REDE / "N fora" text never re-centres (and hops) the icon. */
.cc-cap { position:absolute; left:0; right:0; top:calc(50% + 15px);
  font-family:var(--sans); font-size:8.5px; font-weight:500; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-faint); text-align:center; line-height:1.25;
  display:flex; flex-direction:column; }
.cc-cap em { font-style:normal; text-transform:none; letter-spacing:0; color:var(--ink-faint); }
.ccard.shared .cc-globe svg { stroke:var(--accent); }
.ccard.shared .cc-cap { color:var(--accent); }

/* rediscovery — the overview's heartbeat: it still opens on an image */
.redisc { text-decoration:none; color:var(--ink); }
.redisc .img { overflow:hidden; }
.redisc .img img { width:100%; height:100%; object-fit:cover; display:block; }
.redisc-body { flex:1; min-width:0; }
.redisc-eyebrow { font-size:10px; letter-spacing:.18em; text-transform:uppercase; color:var(--accent); margin-bottom:4px; }
.redisc-sub { font-size:12px; color:var(--ink-faint); margin-top:3px; }
.redisc .chev { width:18px; height:18px; stroke:var(--ink-faint); stroke-width:2; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:none; }

/* drilled-into-a-category header */
.drillhead { margin:2px 0 12px; }
.drillhead .back { display:inline-flex; align-items:center; gap:6px; font-size:13px;
  color:var(--ink-soft); text-decoration:none; width:fit-content; }
.drillhead .back svg { width:18px; height:18px; stroke:currentColor; stroke-width:1.5; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.drillhead h2 { font-family:var(--serif); font-weight:700; font-size:21px; letter-spacing:-.025em; margin-top:9px; }
/* the drill's piece count mirrors the overview's .ovstat exactly, same position */
.drillhead + .ovstat { margin-top:6px; }

/* FAB self-teach pill (first run, retires on first tap) */
/* .fabtip retired (s49) */

/* ============================================================
   TOPAZ type (#8) — lean the older Galeria display headings into
   big bold Inter; the session-4 components are already 700–800.
   Palette warmth comes from the :root tokens above (every color a
   token), so the whole app + the /v approval surface warm for free.
   ============================================================ */
.who h1, .empty h2, .cont .meta h2, .redisc h3, .sheet h4, .topbar .ttl,
.caplead, .cv-head h1, .cv-label h2 { font-weight:700; letter-spacing:-.02em; }
.empty h2 { letter-spacing:-.025em; }
/* Arrumar all-clear (s70, A1): the Trabalhos 'tudo em dia' line at a calm 16px, one line; the
   exit is the app's outlined button shrunk to a single small line (never stacked prose). */
.revclear { padding-top:96px; }
.revclear-line { display:flex; justify-content:center; align-items:center; gap:7px; font-size:16px; font-weight:500; color:var(--ok); }
.revclear-line svg { width:17px; height:17px; stroke:currentColor; stroke-width:2; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.revclear .emptynext { margin-top:14px; }
.revclear .revclear-btn { display:inline-block; width:auto; margin-top:22px; padding:0 22px; line-height:38px; font-size:14px; white-space:nowrap; border-radius:var(--r-ctl); }
/* First pricing encounter (s80): the teaching card on the arrumar receipt, receding to
   a terse pill once the owner has priced anything. */
.priceteach { display:flex; align-items:center; gap:12px; text-align:left; text-decoration:none;
  max-width:330px; margin:18px auto 0; padding:13px 15px; background:var(--paper-2);
  border:1px solid var(--line); border-radius:12px; color:var(--ink); }
.priceteach-ic { width:18px; height:18px; flex:none; fill:none; stroke:var(--accent); stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.priceteach-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.priceteach-body b { font-size:14.5px; font-weight:600; }
.priceteach-body small { font-size:12.5px; color:var(--ink-soft); line-height:1.4; }
.priceteach-chev { width:16px; height:16px; flex:none; fill:none; stroke:var(--ink-faint); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.revclear .priceterse { margin-top:18px; }
/* warm tints for the soft section blocks the topaz look calls for */
.onboard { background:var(--sand); border-color:var(--line-2); }
.conflict-box.warn { background:var(--paper-2); }

/* ---- Rede (cross-collection browse) ---- */
.ovstat { font-size:13.5px; color:var(--ink-soft); margin:2px 2px 14px; letter-spacing:.01em; }
.ovstat-n { font-weight:700; color:var(--ink); font-variant-numeric:tabular-nums; }
.ovstat-clear { color:var(--accent); text-decoration:none; font-weight:600; }

/* filter chips (#39) — categorias/épocas/tamanhos as composable filters, not doors */
.fchips { display:flex; flex-wrap:wrap; gap:8px; margin:0 0 14px; justify-content:center; }
/* Content-sized pills in ONE centered row (s36): with the merged what-is-it chip the
   band is four short labels (Tipo · Tamanho · Época · Gênero) that fit a single line at
   phone width, so the old forced-⅓ grid (which pushed the 4th to a second row) is gone.
   An ACTIVE pill grows to its value + ×; a long value gracefully wraps to a second row
   rather than truncating (.fchips keeps flex-wrap + justify-content:center). .fchipwrap
   stays a wrapper so the active on+× split still reads as one pill. */
.fchipwrap { display:inline-flex; align-items:stretch; }
.fchips .fchipwrap { flex:0 0 auto; }
/* purple pills (s35c): the browse chips carry the accent so meu acervo reads as part of
   the plum system — soft tint body + accent border/text at rest, accent FILL when active.
   No dropdown chevron — the FILTRAR card already says "tap to filter", and dropping it lets
   state read by glyph presence (bare = off, × = on) and fits 3 equal pills per row. */
.fchip { display:inline-flex; align-items:center; justify-content:center; gap:5px;
  border:1px solid var(--accent); border-radius:20px; background:var(--tint); padding:8px 13px;
  font-family:var(--sans); font-size:13.5px; color:var(--accent); cursor:pointer;
  text-decoration:none; -webkit-appearance:none; appearance:none; }
.fchip:active { background:var(--tint-2); }
.fchip.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); font-weight:600;
  border-radius:20px 0 0 20px; }
.fchip-x { display:inline-flex; align-items:center; border:1px solid var(--accent); border-left:none;
  border-radius:0 20px 20px 0; background:var(--accent); color:var(--on-accent); padding:0 11px 0 7px;
  font-size:15px; text-decoration:none; }
.optcount { color:var(--ink-faint); font-size:12.5px; font-variant-numeric:tabular-nums; }
.optrow.on .optcount { color:var(--accent); }

/* batch-select → mesa (#42): a MODE — the browse grid stays pure image until entered */
.selentry { border:none; background:none; padding:2px 8px; margin:-2px -2px; border-radius:999px;
  font:inherit; cursor:pointer; transition:background .12s, color .12s; }
.selentry.on { background:var(--accent); color:var(--on-accent); font-weight:700; }
.tilewrap { position:relative; }
/* Selection tray: the cross-filter picked set, newest first, tap a thumb to uncheck.
   Lives at the top of the feed (not sticky) — one flick up to review, grid never
   reorders under the browsing eye. */
.seltray[hidden] { display:none; }
.seltray { display:flex; gap:8px; overflow-x:auto; padding:2px 2px 12px; -webkit-overflow-scrolling:touch; }
.seltraythumb { position:relative; flex:none; width:44px; aspect-ratio:2/3; border-radius:4px; overflow:hidden;
  border:2px solid var(--accent); background:var(--paper-2); padding:0; cursor:pointer; }
.seltraythumb img { width:100%; height:100%; object-fit:cover; display:block; }
.seltraythumb::after { content:"×"; position:absolute; top:1px; right:1px; width:15px; height:15px;
  border-radius:50%; background:var(--accent); color:var(--on-accent); font-size:11px; line-height:15px;
  text-align:center; font-weight:700; }
/* In select mode the ring IS the tap feedback — suppress the editorial :active outline
   (line 837) so a dark square outline doesn't flash under the green ring on each tap. */
body.selecting .tile:active .img { outline:none; }
.tilewrap.sel::after { content:"✓"; position:absolute; top:8px; right:8px; width:26px; height:26px;
  border-radius:50%; background:var(--accent); color:var(--on-accent); display:grid; place-items:center;
  font-size:15px; font-weight:700; box-shadow:0 1px 5px rgba(20,16,10,.3); pointer-events:none; }
/* selection mode is a contextual action bar (Gmail idiom): it REPLACES the nav+FAB
   at the bottom so nothing collides — the floating FAB was popping up into it. */
body.selecting .navbar { display:none; }
/* Provar panel open: the person-description keyboard floats the fixed nav+FAB up
   onto the green "Gerar" CTA. Hide the bar while describing — same idiom as above. */
body.provaring .navbar { display:none; }
/* The 'Ir pra mesa' floating bar (and its .selbar family) retired — the Mesa nav tab's
   count badge (.navbadge, base.html) carries the pile count instead. */

.expmanual { margin-top:10px; }
.expmanual summary { font-size:13px; color:var(--ink-soft); cursor:pointer; }
.expmanual form { display:flex; flex-direction:column; gap:9px; margin-top:10px; }
.expmanual label { display:flex; flex-direction:column; gap:4px; font-size:12px; color:var(--ink-soft); }
.expmanual input, .expmanual select { padding:9px 11px; border:1px solid var(--line-2); border-radius:2px; background:var(--paper-2); font-size:14px; color:var(--ink); }
.expmanual .exprow2 { display:flex; gap:9px; }
.expmanual .exprow2 label { flex:1; }
/* WRAPS (s30): a month picker + two export buttons never fit one phone line, and
   the old flex:none ran the button off the screen edge. The month field takes the
   whole first row; the two buttons share the second, each growing to fill half. */
.cpaexport { display:flex; flex-wrap:wrap; gap:9px; align-items:stretch; margin-top:6px; }
.cpaexport input[type=month], .cpaexport select { flex:1 1 100%; min-width:0; padding:9px 11px; border:1px solid var(--line-2); border-radius:2px; background:var(--paper-2); font-size:14px; color:var(--ink); }
.cpaexport button { flex:1 1 0; min-width:0; }
/* The PDF is the everyday door; the CSV is the contador's, so it reads quieter. */
.cpaexport button[formaction] { background:var(--paper); color:var(--ink); border:1px solid var(--line-2); }
/* one-time rede notice (#40) — the readiness-gate default is ON, said once */
.sharenotice { display:flex; align-items:center; gap:10px; margin:2px 0 12px; padding:12px 14px;
  border:1px solid var(--line-2); border-radius:12px; background:var(--sand); }
/* Page-intro card (s35i): a large one-time welcome per place — concept + hidden gestures.
   A lifted tinted card so it reads as guidance (not chrome), with a dismiss × top-right. */
.pageintro { position:relative; margin:2px 0 16px; padding:15px 16px 16px;
  border-radius:var(--r-card); background:var(--tint); box-shadow:0 6px 18px var(--shadow); }
.pageintro-hd { font-family:var(--serif); font-weight:800; font-size:19px; letter-spacing:-.01em;
  color:var(--accent); margin:0 26px 4px 0; }
.pageintro-lead { font-size:13.5px; line-height:1.5; color:var(--ink); margin:0; }
.pageintro-list { list-style:none; margin:11px 0 0; padding:0; display:flex; flex-direction:column; gap:7px; }
.pageintro-list li { position:relative; padding-left:18px; font-size:13px; line-height:1.45; color:var(--ink-soft); }
.pageintro-list li::before { content:""; position:absolute; left:2px; top:8px; width:7px; height:7px;
  border-radius:50%; background:var(--accent); }
.pageintro-x { position:absolute; top:8px; right:8px; margin:0; }
.pageintro-x button { border:none; background:none; color:var(--ink-faint); font-size:22px; line-height:1;
  cursor:pointer; padding:6px 8px; min-width:40px; min-height:40px; -webkit-appearance:none; appearance:none; }
.pageintro-x button:active { color:var(--accent); }
/* author display beats the UA [hidden] reset — without this the install card ships
   `hidden` yet paints for every non-owner from first render, and card.hidden=true
   can never take it away (the "un-deletable banner", s33). */
.sharenotice[hidden] { display:none; }
.sharenotice-body { flex:1; min-width:0; display:flex; align-items:center; gap:11px; text-decoration:none; color:var(--ink); }
.sharenotice-body svg { width:20px; height:20px; flex:none; stroke:var(--accent); stroke-width:1.6; fill:none; }
.sharenotice-body span { font-size:13px; line-height:1.4; }
.sharenotice-x { flex:none; border:none; background:none; color:var(--ink-faint); font-size:22px; line-height:1; cursor:pointer; padding:0 4px; }
/* the install card wears the sharenotice coat (s31); the tiny share glyph rides
   inline in the sentence it appears in */
.ic-share { width:14px; height:14px; display:inline-block; vertical-align:-2px;
  stroke:currentColor; stroke-width:1.8; fill:none; }
.ic-go { display:block; margin-top:8px; border:1px solid var(--line-2); background:var(--card);
  border-radius:var(--r-ctl); padding:8px 16px; font-family:var(--sans); font-size:13px;
  font-weight:600; color:var(--accent); cursor:pointer; }
.ic-go[hidden], .ic-ios[hidden], .ic-android[hidden] { display:none; }  /* author display beats the hidden attr */
/* Install guide sheet (s64): shows-not-tells, with drawn browser chrome + a pulsing ring. */
.installsheet-panel { padding:16px 16px 20px; max-height:88vh; overflow-y:auto; }
.inst-head { display:flex; align-items:center; justify-content:flex-end; margin-bottom:8px; }
/* the baked install guide image (s64): full-width, framed so the cream infographic reads
   as a card in both light and dark themes. */
.installsheet .inst-guide { display:block; width:100%; height:auto; border-radius:12px; border:1px solid var(--line-2); }
.inst-head b { font-size:17px; color:var(--ink); }
.inst-x { border:none; background:none; color:var(--ink-faint); font-size:24px; line-height:1; cursor:pointer; padding:0 4px; }
.inst-block[hidden] { display:none; }
.inst-lead { font-size:13.5px; color:var(--ink-soft); margin:0 0 14px; line-height:1.45; }
.inst-why { font-size:12px; color:var(--ink-faint); margin:12px 2px 0; line-height:1.4; }
.inst-done { color:var(--ink); }
.inst-warn { display:flex; gap:10px; align-items:flex-start; background:color-mix(in srgb, var(--terra) 14%, transparent); border-radius:12px; padding:11px 13px; margin-bottom:14px; }
.inst-warn svg { flex:none; width:19px; height:19px; stroke:var(--terra); stroke-width:1.7; fill:none; margin-top:1px; }
.inst-warn span { font-size:13px; color:var(--ink); line-height:1.4; }
.inst-copyrow { display:flex; gap:8px; align-items:center; background:var(--field); border:1px solid var(--line-2); border-radius:10px; padding:9px 11px; margin-bottom:12px; }
.inst-link { flex:1; min-width:0; font-size:13px; color:var(--ink-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.inst-copy { flex:none; border:none; background:none; color:var(--accent); font-size:12.5px; font-weight:600; cursor:pointer; }
.inst-cont { width:100%; border:1px solid var(--line-2); background:none; color:var(--accent); border-radius:10px; padding:11px; font-size:13.5px; font-weight:600; cursor:pointer; }
.inst-onetap { display:block; width:100%; border:none; background:var(--accent); color:var(--on-accent); border-radius:11px; padding:14px; font-size:14.5px; font-weight:600; cursor:pointer; margin-bottom:14px; }
.inst-onetap:active { background:var(--accent-press); }
/* Install COVER (s65): the sheet promoted to a full-cover "necessary step" — the real icon
   anchors it, ONE action per context, a quiet "agora não" escape (never a wall). Reuses the
   .inst-* blocks; only the framing (icon/eyebrow/hero/why/escape) is new. */
.installsheet--cover { align-items:stretch; }
.installsheet--cover .installsheet-panel { max-width:520px; min-height:100%; max-height:none;
  border-radius:0; padding:0; display:flex; flex-direction:column; overflow-y:auto; }
.instcover-x { position:absolute; top:10px; right:12px; z-index:2; border:none; background:none;
  color:var(--ink-faint); font-size:26px; line-height:1; cursor:pointer; padding:2px 6px; }
.instcover-body { flex:1; display:flex; flex-direction:column; align-items:center; text-align:center;
  justify-content:flex-start; width:100%; max-width:400px; margin:0 auto;
  padding:52px 22px 8px; box-sizing:border-box; }
.instcover-ic { width:66px; height:66px; border-radius:16px; display:block; margin-bottom:18px;
  box-shadow:0 6px 18px rgba(60,40,70,.16); }
.instcover-eye { font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent); font-weight:600; }
.instcover-h { font-size:23px; font-weight:600; line-height:1.15; color:var(--ink); margin-top:8px; }
.instcover-why { font-size:13px; color:var(--ink-soft); line-height:1.5; margin:9px 0 16px; }
.installsheet--cover .inst-block:not([hidden]) { width:100%; display:flex; flex-direction:column; align-items:center; }
.installsheet--cover .inst-warn,
.installsheet--cover .inst-lead,
.installsheet--cover .inst-copyrow,
.installsheet--cover .inst-onetap,
.installsheet--cover .inst-cont { width:100%; }
.installsheet--cover .inst-warn { text-align:left; margin-top:6px; }
.installsheet--cover .inst-lead { margin:14px 0; }
.installsheet--cover .inst-guide { display:block; width:auto; max-width:100%; max-height:60vh;
  margin:4px auto 0; }
.instcover-esc { flex:none; border:none; background:none; color:var(--ink-faint); font-size:13.5px;
  cursor:pointer; padding:16px 0 24px; text-align:center; }
.instcover-esc:active { color:var(--ink-soft); }
/* s64: static illustrated install steps — a realistic phone-screen drawing per step with
   a STATIC ring on the target (no motion, his call). Scoped under .installsheet. */
.inst-step { display:flex; gap:12px; align-items:center; padding:12px 0; border-top:1px solid var(--line); }
.inst-step:first-of-type { border-top:none; }
.inst-n { flex:none; width:24px; height:24px; border-radius:50%; background:var(--accent); color:var(--on-accent); font-size:12px; font-weight:600; display:grid; place-items:center; align-self:flex-start; margin-top:4px; }
.inst-t { flex:1; min-width:0; font-size:13px; color:var(--ink); line-height:1.4; }
.inst-t b { font-weight:600; }
.installsheet .scr { width:132px; flex:none; border-radius:16px; border:4px solid #2b2630; background:var(--field); overflow:hidden; box-shadow:0 5px 14px rgba(60,40,70,.14); }
.installsheet .scr-body { height:168px; position:relative; background:linear-gradient(180deg,var(--paper),var(--field)); }
.installsheet .tapring { position:absolute; width:24px; height:24px; border:2.5px solid var(--accent); border-radius:50%; background:var(--tint); z-index:5; pointer-events:none; }
.installsheet .ios-page { position:absolute; inset:0; padding:12px 10px; color:var(--ink-faint); font-size:9px; }
.installsheet .ios-logo { font-size:20px; font-weight:700; color:var(--ink); letter-spacing:-.02em; }
.installsheet .ios-logo i { color:var(--accent); font-style:normal; }
.installsheet .ios-addr { position:absolute; left:10px; right:10px; bottom:36px; height:18px; border-radius:8px; background:var(--paper-2); display:flex; align-items:center; justify-content:center; font-size:8.5px; color:var(--ink-soft); }
.installsheet .ios-bar { position:absolute; left:0; right:0; bottom:0; height:32px; background:var(--paper-2); border-top:1px solid var(--line); display:flex; align-items:center; justify-content:space-around; color:var(--ink-soft); }
.installsheet .ios-bar svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.5; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.installsheet .ios-bar .tgt { position:relative; }
.installsheet .sheet-mock { position:absolute; left:0; right:0; bottom:0; top:22px; background:var(--field); border-radius:13px 13px 0 0; box-shadow:0 -4px 12px rgba(0,0,0,.08); padding:9px 9px 0; overflow:hidden; }
.installsheet .sheet-apps { display:flex; gap:7px; padding:2px 2px 9px; border-bottom:1px solid var(--line); }
.installsheet .sheet-apps i { width:24px; height:24px; border-radius:7px; background:var(--paper-2); display:block; flex:none; }
.installsheet .sm-row { display:flex; align-items:center; justify-content:space-between; padding:7px 5px; border-bottom:1px solid var(--line); font-size:9.5px; color:var(--ink); position:relative; }
.installsheet .sm-row.hot { background:var(--tint); border-radius:7px; font-weight:600; color:var(--accent-press); }
.installsheet .sm-row .ic { width:17px; height:17px; border-radius:5px; background:var(--paper-2); display:grid; place-items:center; font-size:10px; }
.installsheet .sm-row.hot .ic { background:var(--field); }
.installsheet .addbar { position:absolute; top:0; left:0; right:0; height:28px; display:flex; align-items:center; justify-content:space-between; padding:0 16px; border-bottom:1px solid var(--line); background:var(--field); font-size:10px; }
.installsheet .addbar .cancel { color:var(--ink-faint); }
.installsheet .addbar .add { color:var(--accent-press); font-weight:700; background:var(--tint2); border-radius:7px; padding:3px 9px; }
.installsheet .addcard { position:absolute; top:40px; left:10px; right:10px; display:flex; align-items:center; gap:8px; background:var(--field); border:1px solid var(--line); border-radius:9px; padding:8px; }
.installsheet .addcard .ico { width:32px; height:32px; border-radius:8px; background:var(--accent); color:var(--on-accent); display:grid; place-items:center; font-size:8px; font-weight:700; }
.installsheet .addcard .ico i { font-style:normal; }
.installsheet .addcard b { font-size:10px; color:var(--ink); display:block; }
.installsheet .addcard small { font-size:7.5px; color:var(--ink-faint); }
.installsheet .and-top { position:absolute; top:0; left:0; right:0; height:28px; display:flex; align-items:center; gap:6px; padding:0 8px; background:var(--paper-2); border-bottom:1px solid var(--line); font-size:9px; color:var(--ink-soft); }
.installsheet .and-top .url { flex:1; height:15px; border-radius:8px; background:var(--field); display:flex; align-items:center; padding:0 7px; font-size:8px; color:var(--ink-soft); }
.installsheet .and-top .dots { font-size:13px; color:var(--ink); font-weight:700; position:relative; }
.installsheet .and-menu { position:absolute; top:24px; right:7px; width:104px; background:var(--field); border-radius:8px; box-shadow:0 4px 14px rgba(0,0,0,.16); overflow:hidden; font-size:9px; }
.installsheet .and-menu div { padding:7px 9px; border-bottom:1px solid var(--line); color:var(--ink); position:relative; }
.installsheet .and-menu div.hot { background:var(--tint); font-weight:600; color:var(--accent-press); }
.installsheet .and-top .dots.tgt { color:var(--ink); font-weight:700; }
/* s64: iOS 26 real-flow drawings — ⋯ tab bar, the ⋯ menu, the A2HS confirm — + an arrow. */
.installsheet .ios-mut { font-size:9px; color:var(--ink-faint); margin-top:3px; }
.installsheet .ios-tabbar { position:absolute; left:0; right:0; bottom:0; height:30px; display:flex; align-items:center; gap:5px; padding:0 8px; background:var(--paper-2); border-top:1px solid var(--line); font-size:11px; color:var(--ink-soft); }
.installsheet .ios-tabbar .dim { opacity:.4; }
.installsheet .ios-tabbar .addr { flex:1; height:15px; border-radius:8px; background:var(--field); display:flex; align-items:center; justify-content:center; font-size:8px; color:var(--ink-soft); }
.installsheet .ios-tabbar .tgt { font-weight:700; color:var(--ink); }
.installsheet .ios-menu { position:absolute; left:8px; right:8px; bottom:8px; background:var(--field); border-radius:12px; box-shadow:0 6px 18px rgba(0,0,0,.16); overflow:hidden; }
.installsheet .im-row { display:flex; align-items:center; justify-content:space-between; padding:9px 11px; border-bottom:1px solid var(--line); font-size:10px; color:var(--ink); }
.installsheet .im-row:last-child { border-bottom:none; }
.installsheet .im-row.hot { background:var(--tint); font-weight:600; color:var(--accent-press); }
.installsheet .im-row .ic { width:16px; height:16px; color:var(--ink-soft); display:grid; place-items:center; font-size:11px; }
.installsheet .im-row .ic svg { width:13px; height:13px; stroke:currentColor; stroke-width:1.6; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.installsheet .im-row.hot .ic { color:var(--accent-press); }
.installsheet .a2hs { position:absolute; inset:0; background:var(--field); }
.installsheet .a2hs-top { display:flex; align-items:center; justify-content:space-between; padding:9px 10px; border-bottom:1px solid var(--line); font-size:9.5px; }
.installsheet .a2hs-top .x { color:var(--ink-faint); }
.installsheet .a2hs-top .ttl { font-weight:600; color:var(--ink); }
.installsheet .a2hs-top .add { color:var(--on-accent); background:var(--accent); border-radius:20px; padding:3px 11px; font-weight:700; }
.installsheet .a2hs-card { display:flex; align-items:center; gap:8px; margin:13px 10px 0; }
.installsheet .a2hs-card .ico { width:30px; height:30px; border-radius:7px; background:var(--accent); color:var(--on-accent); display:grid; place-items:center; font-size:7px; font-weight:700; }
.installsheet .a2hs-card .ico i { font-style:normal; }
.installsheet .a2hs-card .aname { font-size:11px; font-weight:600; color:var(--ink); border-bottom:2px solid var(--accent); padding-bottom:1px; }
.installsheet .a2hs-tog { display:flex; align-items:center; justify-content:space-between; margin:14px 10px 0; font-size:9px; color:var(--ink); }
.installsheet .a2hs-tog .sw { width:26px; height:15px; border-radius:9px; background:var(--ok); position:relative; flex:none; }
.installsheet .a2hs-tog .sw i { position:absolute; top:1.5px; right:1.5px; width:12px; height:12px; border-radius:50%; background:#fff; }
.installsheet .arw { position:absolute; width:22px; height:22px; color:var(--accent); z-index:7; filter:drop-shadow(0 1px 2px rgba(0,0,0,.28)); }
.installsheet .arw path { fill:currentColor; }
/* the install NUDGE card is a button now (s64) — opens the sheet */
button.installcard { font:inherit; text-align:left; width:100%; cursor:pointer; }
.installcard > svg:first-child { width:20px; height:20px; flex:none; stroke:var(--accent); stroke-width:1.6; fill:none; }
.installcard > span { flex:1; font-size:13px; line-height:1.4; color:var(--ink); }
.installcard-chev { width:18px; height:18px; flex:none; stroke:var(--ink-faint); stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* the master rede switch (#40) — share the whole acervo (ready pieces auto-qualify) */
/* rede — editorial pass (s35, revised per feedback): a compact gradient hero card, section
   eyebrows with a tick, acervo cards with a clamped description + its own location line + a
   tinted count selo. Constellation pulled (too busy over a growing list). Skin only. */
.rede-sub { text-align:left; max-width:24ch; color:var(--ink-soft); margin-top:5px; }

/* The card FILL carries state now (s35): plum = truly on air, muted = out (off OR
   blocked). The old base was plum in BOTH states, so on/off looked identical. */
.redeswitch { position:relative; overflow:hidden; display:flex; align-items:center; gap:13px; margin:14px 0 6px;
  padding:13px 15px; border:1px solid var(--line); border-radius:var(--r-card); background:var(--card); color:var(--ink);
  box-shadow:0 4px 14px var(--shadow); }
.redeswitch.on { border-color:transparent; background:var(--grad); color:#fff; }
.redeswitch-eye { flex:none; width:38px; height:38px; border-radius:50%; background:var(--paper-2);
  display:grid; place-items:center; }
.redeswitch.on .redeswitch-eye { background:rgba(255,255,255,.16); }
.redeswitch-eye svg { width:19px; height:19px; stroke:var(--ink-soft); fill:none; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.redeswitch.on .redeswitch-eye svg { stroke:#fff; }
.redeswitch-body { flex:1; min-width:0; }
.redeswitch-body b { font-size:14.5px; font-weight:600; }
.redeswitch-body span { display:block; font-size:12px; color:var(--ink-soft); margin-top:3px; line-height:1.38; }
.redeswitch.on .redeswitch-body span { color:rgba(255,255,255,.80); }
/* the toggle shows INTENT (share on/off), so it stays legible on both card fills:
   accent on the muted card, white-translucent on the plum one. */
.redeswitch-toggle { flex:none; width:46px; height:27px; border-radius:var(--r-pill); border:none; padding:0;
  background:var(--line-2); position:relative; cursor:pointer; transition:background .18s; -webkit-appearance:none; appearance:none; }
.redeswitch-toggle[aria-checked="true"] { background:var(--accent); }
.redeswitch.on .redeswitch-toggle { background:rgba(255,255,255,.26); }
.redeswitch.on .redeswitch-toggle[aria-checked="true"] { background:rgba(255,255,255,.45); }
.redeswitch-knob { position:absolute; top:3px; left:3px; width:21px; height:21px; border-radius:50%;
  background:#fff; transition:transform .18s; box-shadow:0 1px 3px rgba(0,0,0,.25); }
.redeswitch-toggle[aria-checked="true"] .redeswitch-knob { transform:translateX(19px); }
/* the reason + fix under a blocked-but-on card (folded from the old standalone redegate) */
.redeswarn { display:flex; align-items:center; gap:8px; margin:2px 0 6px; padding:9px 12px;
  border-radius:12px; background:var(--warn-tint); color:var(--warn); text-decoration:none;
  font-family:var(--sans); font-size:12.5px; line-height:1.4; }
.redeswarn svg { width:17px; height:17px; flex:none; stroke:currentColor; fill:none; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.redeswarn b { font-weight:600; }

/* No ar line (s41): the healthy broadcast state as ONE quiet muted row, pinned above the
   unbounded acervos so its toggle stays reachable. Compact, reuses the switch's toggle;
   its BROKEN states use the loud card instead. */
.redefoot { display:flex; align-items:center; gap:10px; margin:14px 2px 4px; padding:2px 0; }
.redefoot-eye { flex:none; color:var(--ink-soft); display:flex; }
.redefoot-eye svg { width:18px; height:18px; stroke:currentColor; fill:none; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.redefoot-txt { flex:1; min-width:0; font-size:12.5px; color:var(--ink-soft); line-height:1.4; }
.redefoot-txt b { color:var(--ink); font-weight:600; }
.redesec, .invlabel { display:flex; align-items:center; gap:9px; font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-soft); font-weight:700; }
.redesec { margin:24px 0 12px; }
/* THE SELF-ANCHOR (s54): one compact line — your on-air status + the toggle — replacing the
   old "No ar" foot line AND the full você card (both showed your piece count). */

/* FILTER CHIPS (s54): scope the search-first rede — Tudo · Peças · Acervos · Serviços. */

/* THE GUILD BANDS (s54): sub-headers within Acervos — Seu círculo / Perto de você / Na rede.
   Lighter than .redesec (it's a zone inside the section). */
.guildband { display:flex; align-items:center; gap:8px; margin:20px 0 9px; font-size:11px;
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink-faint); font-weight:700; }
/* circle members (people connected to you) wear a plum-ringed avatar */
.shopcard-circle .shopav { box-shadow:0 0 0 2px var(--card), 0 0 0 3.5px var(--accent); }
/* member cards (s54): the vibe/craft chip carries the colour (replaces the grey specialty
   line); a produtora card is flat with a WhatsApp door instead of a piece-count pill. */
.shopchips { display:flex; gap:5px; min-height:19px; align-items:center; margin:1px 0; }
.shopchip { display:inline-flex; align-items:center; font-size:11.5px; font-weight:600;
  color:var(--accent); background:var(--tint); border-radius:8px; padding:3px 8px; max-width:100%; }
.shopchip-t { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* THE PRESENCE CARD (s58, [[rede-two-layers-identity]]): the directory is the scene, so a MAKER's
   card shows their SERVICES (what they do) as pink chips behind a scissors — labour is their whole
   offering, no stock-loja to open. Acervos carry no inventory line (that's search's job). Rows size
   to what they carry (reverses the s50 one-shape-per-row equalisation). */
.shopserv-i { fill:none; stroke:var(--dot); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.shopcard-maker { cursor:default; }
.shopzap { flex:none; width:44px; height:44px; border-radius:50%; background:var(--ok);
  display:grid; place-items:center; text-decoration:none; }
.shopzap svg { width:22px; height:22px; fill:var(--on-accent); }

.shoplist { display:flex; flex-direction:column; background:var(--card); border-radius:var(--r-card);
  overflow:hidden;
  box-shadow:0 6px 22px var(--shadow); }   /* lift by shadow alone — no border outline (s58) */
.shopcard { display:flex; align-items:center; gap:13px; padding:14px 16px; text-decoration:none; color:var(--ink); }
.shoplist .shopcard + .shopcard { border-top:1px solid var(--hair); }   /* divider between stacked roster cards */
.shopcard:active { background:var(--paper-2); }
/* s58 — the face is the identity payload (the card's warmth source), so it dominates:
   50→72px. The count demotes to the place line; the face grows into the room it leaves. */
/* --av-col (s83, his call): EVERY rede card reserves the same avatar column, photo or not — a
   smaller no-photo disc centres inside it, so avatar centres and the text beside them line up
   down the list whatever sizes these become. */
.shopav { --av-col:72px; flex:none; width:var(--av-col); height:var(--av-col); aspect-ratio:1; border-radius:50%; background:var(--accent);
  color:var(--on-accent); display:flex; align-items:center; justify-content:center; font-weight:600; font-size:28px; overflow:hidden; }
.shopav img { width:100%; height:100%; object-fit:cover; }
.shopav.lg { width:72px; height:72px; font-size:28px; }

/* the name row: name (ellipsised) + the ✂ services glyph (never clips) */
.shopnrow { display:flex; align-items:center; gap:7px; min-width:0; }
.shopnrow b { min-width:0; }
.shopnrow .shopserv-i { flex:none; width:16px; height:16px; }
/* the count, demoted onto the place line but unmistakably a COUNT: plum + bold (the app's
   stat colour, learned from the old count pill) so it pops from the faint grey location it
   rides beside, instead of reading as more of the address (s58). MUST out-specify the
   `.shoploc-lines span { display:block }` rule (0,1,1) it sits inside — otherwise the count
   becomes a block on its own line and gets clipped by the parent's fixed height + overflow. */
.shoploc-lines .shopn-inline { display:inline; color:var(--accent); font-weight:600; font-variant-numeric:tabular-nums; }
/* ONE SHAPE PER ROW (s50, his call): name and specialty one line each with an ellipsis,
   the place always two lines (bairro / cidade), so no row is ever taller than its
   neighbour — whatever the words, the count, or the tag. */
.shopmeta { flex:1; display:flex; flex-direction:column; gap:3px; min-width:0; }
.shopmeta b { font-size:16px; font-weight:600; letter-spacing:-.01em; line-height:1.2; display:block;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.shopdesc { font-size:12.5px; color:var(--ink-soft); line-height:1.35; height:17px;
  display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.shoploc { display:flex; align-items:flex-start; gap:4px; font-size:11.5px; line-height:1.35; color:var(--ink-faint); }
.shoploc svg { flex:none; width:12px; height:12px; margin-top:1.5px; stroke:currentColor; fill:none; stroke-width:1.6; }
.shoploc-lines { min-width:0; flex:1; }
.shoploc-lines span { display:block; height:15.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.shopchev { flex:none; color:var(--ink-faint); display:flex; }
.shopchev svg { width:17px; height:17px; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.shophead { display:flex; align-items:center; gap:14px; margin:8px 0 18px; }
.shopname { font-size:26px; font-weight:700; letter-spacing:-.02em; margin:0; }
.redeowner { text-align:center; font-size:14px; color:var(--ink-soft); margin:14px 0; }
.redewa { display:block; text-align:center; margin:6px auto 4px; max-width:320px; }
/* s48 base tier: the rede ask is a WhatsApp-shaped photo share — the one green
   primary in the app (--wa is a brand affordance, fixed in both themes). */
.btn.primary.wago { background:var(--wa); border-color:#25613E; width:100%; max-width:none; margin-top:4px; }
.btn.primary.wago:active { background:#25613E; }
/* ── THE SELL VERB (s48, the rack-OS widening): the Venda row's chips + stamp. ──
   The price qfield must NEVER be squeezable (his phone report: the base .qfield's
   flex:1 let the row crush it to 52px while its fixed 88px input overflowed
   backward over the chip) — every child is flex:none and narrow rows WRAP. */
.salerow .v { display:flex; align-items:center; justify-content:flex-end;
  gap:8px 10px; flex-wrap:wrap; }
.salerow .qfield.qmoney { flex:0 0 auto; }
.salechip { border:1px solid var(--line-2); background:var(--card); color:var(--ink-soft);
  border-radius:var(--r-pill); padding:5px 12px; font-family:inherit; font-size:12.5px;
  font-weight:600; cursor:pointer; -webkit-appearance:none; appearance:none; }
.salechip.on { background:var(--chip-ok-bg); color:var(--chip-ok-ink); border-color:transparent; }
.salechip.sold { background:var(--accent); color:var(--on-accent); border-color:transparent; }
.soldsheet-form { display:flex; flex-direction:column; gap:14px; padding:4px 2px 10px; }
.soldsheet-form .btn.primary { max-width:none; }
/* s75 (his call): the R$ box and the input beside it are the SAME height (the stretch was
   leaving the R$ box taller), and the field pair sits CENTERED between its label and the
   submit — equal breathing room above (label→field) and below (field→button), not jammed
   under the label. One field height for every input in the sheet. */
.soldsheet-form .f { display:flex; flex-direction:column; gap:14px; }
.soldsheet-form .moneywrap { align-items:stretch; }
.soldsheet-form .fld, .soldsheet-form .moneywrap .rsym { height:46px; box-sizing:border-box; }
.soldsheet-form .fld { padding-top:0; padding-bottom:0; }
.saleundo { border:0; background:none; color:var(--ink-faint); font-family:inherit;
  font-size:12px; cursor:pointer; text-decoration:underline; padding:0 0 0 6px; }
.redesale { text-align:center; font-size:13.5px; font-weight:700; color:var(--chip-ok-ink);
  margin:2px 0 8px; }
/* s58 — a não-aluga cull leads with its sale price (the rental lead is hidden), so the
   sale line takes the lead size that redeprice2 vacated. */
.redesale-lead { font-size:22px; margin:14px 0 8px; }
.pedir-none { text-align:center; font-size:13.5px; color:var(--ink-soft); margin:4px 0 2px; }
.vtile-sale { position:absolute; left:8px; bottom:8px; z-index:2; font-size:10.5px;
  font-weight:700; letter-spacing:.04em; background:var(--chip-ok-bg);
  color:var(--chip-ok-ink); border-radius:999px; padding:3px 9px; }

/* The rede availability fact (s48, idea C): quiet warn line, dates only. */
.redebusy { text-align:center; font-size:12.5px; font-weight:600; color:var(--chip-warn-ink);
  background:var(--chip-warn-bg); border-radius:999px; padding:5px 14px;
  width:fit-content; margin:2px auto 10px; }
/* Paste-the-conversation (s48, idea E): a quiet disclosure above the form. */
.threaddoor { background:var(--card); border:1px solid var(--line); border-radius:12px;
  padding:0; margin:2px 0 18px; }
.threaddoor summary { display:flex; align-items:center; gap:9px; padding:12px 14px;
  font-size:13.5px; font-weight:600; color:var(--wa); cursor:pointer; list-style:none;
  -webkit-tap-highlight-color:transparent; }
.threaddoor summary::-webkit-details-marker { display:none; }
.threaddoor summary svg { width:17px; height:17px; flex:none; }
.threaddoor textarea { display:block; width:calc(100% - 28px); margin:0 14px 10px;
  border:1px solid var(--line-2); background:var(--field); border-radius:10px;
  padding:10px 12px; font:inherit; font-size:13.5px; color:var(--ink); resize:vertical; }
.threaddoor .btn { display:block; margin:0 14px 6px; width:calc(100% - 28px); }
.threaddoor .hint { display:block; margin:0 14px 12px; text-align:center; }
.inviteblock { margin:26px 0 8px; }
.inviteblock summary { font-size:14px; color:var(--ink-soft); cursor:pointer; }
.inviteblock form { display:flex; flex-direction:column; gap:8px; margin-top:12px; }
.inviteblock input { padding:11px 13px; border:1px solid var(--line-2); border-radius:2px; background:var(--paper-2); font-size:15px; }
/* The invite's send row — the moment the rede actually starts. */
.inviteacts { display:flex; gap:9px; margin:12px 0 6px; }
.inviteacts .btn { flex:1; text-align:center; }
.invitebox { margin:16px 0 8px; display:flex; flex-direction:column; gap:6px; }
.invitebox label { font-size:12px; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-soft); }
.invitebox input { padding:11px 13px; border:1px solid var(--line-2); border-radius:2px; background:var(--paper-2); font-size:14px; font-family:ui-monospace,monospace; }
.borrowlist { display:flex; flex-direction:column; gap:2px; }
.borrowcard { display:flex; align-items:center; gap:12px; padding:12px 4px; border-bottom:1px solid var(--line); }
.borrowthumb { flex:none; width:48px; height:60px; border-radius:2px; overflow:hidden; background:var(--paper-2); display:flex; align-items:center; justify-content:center; }
.borrowthumb img { width:100%; height:100%; object-fit:cover; }
.borrowthumb svg { width:28px; height:35px; opacity:.4; }
.borrowmeta { flex:1; display:flex; flex-direction:column; gap:3px; min-width:0; }
.borrowmeta b { font-size:15px; font-weight:600; }
.borrowmeta small { font-size:13px; color:var(--ink-soft); }
.borrowmeta .cardstage { align-self:flex-start; }
.borrowwa { flex:none; width:38px; height:38px; border-radius:50%; border:1px solid var(--line-2); display:flex; align-items:center; justify-content:center; color:var(--accent); }
.borrowwa svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.6; }

/* ---- Perfil & Vitrine ---- */
.avatar { text-decoration:none; font-weight:700; }
.avatar img { width:100%; height:100%; object-fit:cover; }

.setrow { display:flex; align-items:center; justify-content:space-between; gap:12px; text-decoration:none; color:var(--ink); border:1px solid var(--line); border-radius:var(--r-ctl); padding:12px 14px; margin-top:10px; }
.setrow b { font-weight:600; font-size:15px; }
.setrow small { display:block; font-size:12px; color:var(--ink-soft); margin-top:2px; }
.setrow svg { width:20px; height:20px; fill:none; stroke:var(--ink-faint); stroke-width:1.6; flex:none; }
.setrow.static { opacity:.65; }
/* the access-link row is a BUTTON wearing the setrow coat (s31) */
button.setrow.accesslink { width:100%; text-align:left; background:none; cursor:pointer;
  font-family:var(--sans); color:var(--ink); }

/* AJUSTES regroup (s31 S/N): 'Preferências' / 'Conta' sit one tier under the
   'ajustes.' h1 (serif, so they read stronger than the uppercase item .slabels
   but quieter than the page title). */
/* Section header = the meu-acervo FILTRAR eyebrow (pink dash + uppercase), a size up
   (s35i) — so the sections read at a glance instead of floating. */
.setgroup { display:flex; align-items:center; gap:9px; font-family:var(--sans); font-size:13px;
  font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-faint); margin:30px 2px 4px; }
.setgroup + .slabel { margin-top:12px; }
.setgroup + .setcard { margin-top:12px; }
/* AJUSTES is its own section (s35i): pull it well clear of the Preços drawer above with a
   hairline + space, and bring Preferências UP close under the title (it read orphaned). */
.ajustes { margin-top:34px; padding-top:24px; border-top:1px solid var(--line); }
.ajustes > .title { padding-top:0; }
.ajustes .setgroup:first-of-type { margin-top:16px; }
/* Preferências rows (s31, Option C): small-caps label left, a compact segmented
   switch right. Segments are equal-width (flex:1 in a fixed track) so Claro/Escuro
   read as one balanced control; both switches share a width so they align. */
.setseg { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:16px; }
.setgroup + .setseg { margin-top:14px; }
/* Preferences section card (s35i): the switches grouped in one lifted card, hairline-
   separated + tighter, so they stop floating apart. */
.setcard { background:var(--card); border-radius:var(--r-card); box-shadow:0 6px 18px var(--shadow); padding:2px 14px; }
/* Lixeira row (s62): wears the Preferências card's cream + shadow instead of the bordered-paper
   setrow dress, so it reads as a card, not a plain link. */
.setcard .setseg { margin-top:0; padding:13px 0; border-top:1px solid var(--line); }
.setcard .setseg:first-child { border-top:none; }
.setseg + .slabel { margin-top:20px; }
.setseg .slabel { margin:0; }
.segtoggle.segtoggle-3 { width:214px; }   /* three words need the room (s50) */
.unitseg { margin-top:12px; }
.unitseg + .hint { display:block; margin:6px 0 12px; }
.segtoggle { display:flex; width:150px; flex:none; border:1px solid var(--line); border-radius:var(--r-ctl); overflow:hidden; background:var(--card); }
.segopt { flex:1; display:flex; align-items:center; justify-content:center; padding:9px 6px; font-size:13.5px; color:var(--ink-soft); cursor:pointer; border-left:1px solid var(--line); }
.segopt:first-child { border-left:none; }
.segopt input { position:absolute; opacity:0; width:0; height:0; }
.segopt:has(input:checked) { background:var(--accent); color:var(--on-accent); font-weight:600; }
/* Uso de IA collapses to a setrow-styled summary that matches the Backup row; the
   receipt (.aiusage) drops below it, borderless, only when tapped open. */
.aiu-drawer { margin-top:10px; }
.aiu-drawer > summary { list-style:none; cursor:pointer; }
.aiu-drawer > summary::-webkit-details-marker { display:none; }
.aiu-drawer > summary.setrow { margin-top:0; }
.aiu-chev { transition:transform .18s ease; }
.aiu-drawer[open] .aiu-chev { transform:rotate(90deg); }
.aiu-sum-over b, .aiu-sum-over small { color:var(--danger); }
.aiu-sum-over svg { stroke:var(--danger); }
/* s49 (his phone: 'the drawer bleeds into what's below'): the purple summary is the LID —
   open, it squares its bottom corners and a bordered body hangs from it holding the legend,
   the month line, the list and Recarregar. Closed, four corners. One card, one object. */
.aiu-drawer[open] > summary.setrow { border-radius:var(--r-ctl) var(--r-ctl) 0 0; }
.aiu-drawer .aiusage { border:1px solid var(--line-2); border-top:0; border-radius:0 0 var(--r-ctl) var(--r-ctl);
  background:var(--card); padding:12px 16px 14px; margin-top:0; }
/* Créditos summary = the plum drawer style (s35i, matching Preços e regras): dark plum,
   TITLE in Versalete (uppercase, spaced), the sub-line keeps its own font — just lightened
   to read on plum. The zero-credits alert stays legible on plum as light amber, not dark red. */
.aiu-drawer > summary.setrow { background:var(--grad); border:none; color:#FBF7F0; }
.aiu-drawer > summary.setrow b { color:#FBF7F0; font-size:12.5px; font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
.aiu-drawer > summary.setrow small { color:rgba(251,247,240,.78); }
.aiu-drawer > summary.setrow .aiu-chev { stroke:#FBF7F0; }
.aiu-drawer > summary.aiu-sum-over b { color:#F2C879; }
.aiu-drawer > summary.aiu-sum-over small { color:rgba(242,200,121,.85); }
.aiu-drawer > summary.aiu-sum-over .aiu-chev { stroke:#F2C879; }
/* the pink AI sparkle next to the CRÉDITOS title (s35i) — rose, on the plum. Scoped high
   so it beats `.setrow svg { fill:none; stroke }`, which would otherwise hide it. */
.aiu-drawer > summary .credspark { width:13px; height:13px; fill:var(--dot); stroke:none; margin-left:6px; vertical-align:-1px; }
/* Acesso row (s41): the collapsed drawer — same plum-summary look as Créditos, but a plain
   button that opens the renew sheet on tap (chevron reads "opens", never "expands"). */
.acessorow { width:100%; -webkit-appearance:none; appearance:none; background:var(--grad);
  border:none; color:#FBF7F0; font-family:var(--sans); cursor:pointer; text-align:left; }
.acessorow b { color:#FBF7F0; font-size:12.5px; font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
.acessorow small { color:rgba(251,247,240,.78); }
.acessorow .aiu-chev { stroke:#FBF7F0; transform:none; }
.acessorow.aiu-sum-over b { color:#F2C879; }
.acessorow.aiu-sum-over small { color:rgba(242,200,121,.85); }
.acessorow.aiu-sum-over .aiu-chev { stroke:#F2C879; }

.aiusage { border:1px solid var(--line); border-radius:2px; padding:14px; margin-top:10px; }
.aiu-tot { display:flex; gap:14px; }
.aiu-cell { flex:1; }
.aiu-lbl { display:block; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-faint); }
.aiu-val { display:block; font-family:var(--serif); font-weight:600; font-size:24px; margin-top:3px; font-variant-numeric:tabular-nums; }
.aiu-rows { list-style:none; margin:14px 0 0; padding:12px 0 0; border-top:1px solid var(--line); }
.aiu-rows li { display:flex; align-items:baseline; gap:10px; padding:5px 0; font-size:13px; }
.aiu-f { flex:1; color:var(--ink-soft); }
.aiu-n { font-size:11.5px; color:var(--ink-faint); font-variant-numeric:tabular-nums; }
.aiu-c { font-weight:600; font-variant-numeric:tabular-nums; min-width:64px; text-align:right; }
.aiu-empty { margin-top:12px; font-size:13px; color:var(--ink-faint); }
.aiu-note { margin-top:12px; font-size:11.5px; color:var(--ink-faint); line-height:1.5; }
/* the action button (recarga / renovar acesso) never hugs the note above it. */
.aiusage > .btn { margin-top:14px; }
.aiu-val small { font-family:var(--sans); font-weight:400; font-size:12px; color:var(--ink-faint); }
.aiu-usd { display:block; font-size:11px; color:var(--ink-faint); font-variant-numeric:tabular-nums; }
.aiu-overval, .aiu-overval small { color:var(--danger); }
.aiu-cap { display:flex; align-items:center; gap:10px; margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
.aiu-cap .aiu-lbl { flex:1; }
.aiu-capin { display:inline-flex; align-items:center; gap:5px; font-size:13px; color:var(--ink-faint); }
.aiu-capro { font-size:13.5px; color:var(--ink); }
.aiu-capro small { font-size:12px; color:var(--ink-faint); }
.aiu-capin input { width:92px; padding:7px 9px; border:1px solid var(--line-2); border-radius:2px;
  background:var(--card); color:var(--ink); font-size:14px; font-variant-numeric:tabular-nums; text-align:right; }
.aiu-capsave { padding:7px 13px; border:1px solid var(--line-2); border-radius:2px; background:var(--card);
  color:var(--ink-soft); font-size:12.5px; font-weight:600; cursor:pointer; }
.aiu-blocked { margin-top:10px; font-size:12.5px; color:var(--danger); line-height:1.5; }

.pfmedia { position:relative; margin:6px 0 52px; }
.pfcover { display:block; width:100%; aspect-ratio:5 / 2; border-radius:6px; background:var(--paper-2) center/cover no-repeat; border:none; position:relative; cursor:pointer; padding:0; margin:0; font:inherit; color:inherit; text-align:left; -webkit-appearance:none; appearance:none; }
/* Empty capa (s80, his call): the default banner_1.png (was the plum gradient var(--grad)),
   matching the VITRINE's .vcover — so the edit view previews exactly what the public
   storefront shows when there's no cover photo. Only while empty; a real cover bleeds its
   photo edge-to-edge over it. */
.pfcover-empty { border:none; background:url('/static/banner_1.png') center/cover no-repeat; }
.pfcover input { position:absolute; inset:0; opacity:0; cursor:pointer; }
.pfedit { position:absolute; right:10px; bottom:10px; background:rgba(40,28,48,.72); color:#fff; font-size:11px; padding:5px 10px; border-radius:20px; display:inline-flex; gap:5px; align-items:center; }
.pfedit svg { width:13px; height:13px; fill:none; stroke:#fff; stroke-width:1.8; }
.pfavatar { position:absolute; left:16px; bottom:-32px; width:88px; height:88px; border-radius:50%; overflow:hidden;
  border:3px solid var(--paper); background:var(--accent); color:#fff; padding:0; cursor:pointer; display:grid;
  place-items:center; box-shadow:0 3px 12px -4px rgba(40,28,48,.45); }
.pfavatar img { width:100%; height:100%; object-fit:cover; display:block; }
.pfavatar-init { font-size:32px; font-weight:700; }
.pfavatar-empty input { position:absolute; inset:0; opacity:0; cursor:pointer; }
.pfavatar-cam { position:absolute; left:0; right:0; bottom:0; height:34%; display:flex;
  align-items:flex-end; justify-content:center; padding-bottom:6px;
  background:linear-gradient(transparent, rgba(40,28,48,.6)); pointer-events:none; }
.pfavatar-cam svg { width:18px; height:18px; fill:none; stroke:#fff; stroke-width:1.7; }
.fiscal { margin:8px 0; }
/* breathing rhythm (s25): a field group owns its hint; the next label must not
   crowd the previous box. NOT flex-gap: <details> slots its content internally,
   so gap on it COMPUTES but never renders (the old 16px silently did nothing —
   the crowding Matias flagged). Child margins render everywhere. */
.fiscal[open] > * + * { margin-top:20px; }
.catprices[open] > .catprice-row + .catprice-row { margin-top:0; }
/* Disclosure idiom (s35i canon pass): the fiscal/preços drawers wear the .setrow shape
   + a chevron that rotates on open, matching the wallet drawer — no raw <details> ▶. */
.fiscal > summary { list-style:none; cursor:pointer; }
.fiscal > summary::-webkit-details-marker { display:none; }
.fisc-chev { transition:transform .18s ease; }
.fiscal[open] > summary .fisc-chev { transform:rotate(90deg); }
/* Dark plum, white text (s35i): the two drawers are the section anchors — plum so they
   stay easy to spot while scrolling AND when open (the mesa/rede/filtrar idiom). */
.fiscal > summary.setrow { background:var(--grad); border:none; color:#FBF7F0; }
/* Versalete (s35i, his pick A): the drawer label reads as a section header — uppercase,
   spaced — not body text. */
.fiscal > summary.setrow b { color:#FBF7F0; font-size:12.5px; font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
.fiscal > summary.setrow .fisc-chev { stroke:#FBF7F0; }
.fiscal-note { font-size:12px; color:var(--ink-faint); line-height:1.45; margin:-4px 0 -2px; }
.suggestion { display:inline-flex; align-items:center; gap:6px; margin-top:8px; font-size:12.5px;
  background:var(--tint); border:none; border-radius:var(--r-ctl); padding:8px 12px;
  color:var(--accent); cursor:pointer; font-family:var(--sans); font-weight:600; }
.suggestion:disabled { opacity:.6; }
/* Pink AI sparkle (s35i): the ✨ emoji was locked yellow — an SVG takes the rose accent. */
.sugstar { width:14px; height:14px; flex:none; fill:var(--dot); }
/* White identity fields (s35i): the top-of-perfil fields lift off the paper as white — the
   fiscal-drawer fields (inside details.fiscal, not a direct .f child) stay untouched, and
   the WhatsApp +55 prefix (.ccode span) is not an input so it keeps its own tone. */
.pfform > .f input, .pfform > .f textarea,
.pfform > .f2 .f input, .pfform > .f2 .f select { background:var(--card); }
/* …and every field inside both drawers too (s35i): the nota/contrato fields, the Preços
   wall-list money inputs, and the acréscimos % — all white. */
.fiscal input, .fiscal textarea, .fiscal select { background:var(--card); }

/* nova locação (s38 → s39): its data-entry fields lift off the paper as true FIELD
   white (--field — --card didn't read as white). And the phonewrap needs the same
   9px gap the .fld carries, so the Job field below it doesn't crowd the number. */
.rform .fld, .rform .phonewrap input, .rform .moneywrap input,
.rform .datefld input { background:var(--field); }
.rform .phonewrap { margin-bottom:9px; }

/* avatar crop editor (#profile-photo) — open larger, pan + zoom into a circle,
   trocar (in-circle chip) / remover / salvar. The circle itself is the picker. */
.avedit[hidden] { display:none; }
.avedit { position:fixed; inset:0; z-index:96; display:flex; align-items:center; justify-content:center; padding:20px; }
.avedit-backdrop { position:absolute; inset:0; background:rgba(40,28,48,.5); }
.avedit-panel { position:relative; width:min(92vw,360px); background:var(--paper); border-radius:18px;
  padding:20px 20px 18px; box-shadow:0 20px 50px -12px rgba(40,28,48,.5); }
.avedit-panel h4 { font-size:16px; font-weight:700; margin:0 0 14px; }
.avedit-stage { position:relative; width:100%; aspect-ratio:1; border-radius:12px; overflow:hidden;
  background:#1a1a1a; touch-action:none; cursor:grab; }
.avedit-stage.cvstage { aspect-ratio:5 / 2; }   /* the capa banner — ONE ratio (5:2) shared with the editor output (1500×600) and both display surfaces (.pfcover, .vcover), so the crop you compose is pixel-faithful in the vitrine */
.sigedit .avedit-stage { aspect-ratio:5 / 2; background:#f2ede4; }  /* a signature is wide — frame the ink, leave stray marks outside; paper-toned so any uncovered edge reads as background, never as ink */
.sigedit .avedit-empty { color:rgba(20,16,10,.5); }
.avedit-rotate-row { display:flex; align-items:center; gap:10px; margin:10px 2px 2px; }
.avedit-rotate-ic { width:16px; height:16px; flex:0 0 auto; fill:none; stroke:var(--ink-faint); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.avedit-rotate { flex:1; -webkit-appearance:none; appearance:none; height:3px; border-radius:2px; background:var(--line-2); }
.avedit-rotate::-webkit-slider-thumb { -webkit-appearance:none; width:18px; height:18px; border-radius:50%; background:var(--accent); cursor:pointer; }
.avedit-rotate::-moz-range-thumb { width:18px; height:18px; border:none; border-radius:50%; background:var(--accent); cursor:pointer; }
.avedit-stage:active { cursor:grabbing; }
.avedit-stage img { position:absolute; user-select:none; -webkit-user-drag:none; max-width:none; }
.avedit-empty[hidden] { display:none; }
.avedit-empty.err { color:#F2B8A0; padding:0 22px; text-align:center; line-height:1.45; }
.avedit-empty { position:absolute; inset:0; display:grid; place-items:center; color:rgba(255,255,255,.7);
  font-size:13px; text-align:center; padding:24px; pointer-events:none; }
/* s83 (his call): Trocar sits in the TITLE ROW, upper-right ABOVE the picture — never over what's
   being framed. On the cream panel it's a quiet outline pill (the dark glass pill was for photos). */
.avedit-head { display:flex; align-items:center; justify-content:space-between; gap:10px; margin:0 0 14px; }
.avedit-head h4 { margin:0; min-width:0; }
.avedit-change { position:relative; flex:none; display:inline-flex; align-items:center; gap:5px;
  background:none; border:1px solid var(--line-2); color:var(--ink-soft);
  font-size:12.5px; padding:6px 12px; border-radius:20px; cursor:pointer; }
.avedit-change svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.8; }
.avedit-change input { position:absolute; inset:0; opacity:0; cursor:pointer; }
.avedit-ring { position:absolute; inset:0; pointer-events:none; }
.avedit-ring::after { content:""; position:absolute; top:50%; left:50%; width:100%; height:100%;
  transform:translate(-50%,-50%); border-radius:50%; box-shadow:0 0 0 9999px rgba(20,16,12,.5);
  border:2px solid rgba(255,255,255,.65); }
.avedit-hint[hidden] { display:none; }
.avedit-hint { text-align:center; font-size:11.5px; color:var(--ink-faint); margin:10px 0 2px; }
.avedit-actions { display:flex; gap:8px; margin-top:10px; }
.avedit-actions .btn { flex:1; margin:0; cursor:pointer; }
.avedit-actions .btn.danger { color:var(--brick); border-color:var(--line-2); background:var(--card); }
.avedit-actions .btn.primary { background:var(--accent); color:#fff; border-color:var(--accent); }
.avedit-actions .btn:disabled { opacity:.5; }
.avedit-actions .btn[hidden] { display:none; }  /* the .btn display rule otherwise defeats the hidden attr (the framer hides Remover on a fresh pick) */
.avedit-cancel { display:block; width:100%; text-align:center; background:none; border:none;
  color:var(--ink-soft); font-size:14px; margin-top:12px; padding:6px; cursor:pointer; }

/* nopad lets the cover bleed edge-to-edge — but it zeroed the BOTTOM too, so the
   vitrine's and the loja's last row of pieces sat behind the fixed navbar (s25).
   Same 140px clearance every other .content reserves. */
.content.nopad { padding:0 0 140px; }
.vcover { width:100%; aspect-ratio:5 / 2; background:url('/static/banner_1.png') center/cover no-repeat; position:relative; }
.vback { position:absolute; top:14px; left:12px; display:inline-flex; align-items:center; gap:5px; background:rgba(22,18,28,.5); color:#fff; font-size:13px; padding:6px 11px; border-radius:var(--r-pill); text-decoration:none; }
.vback svg { width:16px; height:16px; fill:none; stroke:#fff; stroke-width:1.8; }
.vbody { padding:0 20px; }
/* s80→s82 (his call): the no-photo perfil disc is FLAT plum with a soft gradient (the s80 shaded
   sphere image read too polished/raised) + the cream initial. A real photo covers it via the <img>. */
.vphoto { position:relative; z-index:1; width:80px; height:80px; border-radius:50%; overflow:hidden; border:3px solid var(--paper); margin:-42px 0 0; display:grid; place-items:center; background:linear-gradient(150deg,#705285 0%,#4D375F 100%); color:#FBF7F0; font-size:30px; font-weight:700; }
.vphoto img { width:100%; height:100%; object-fit:cover; }
.vname { font-size:26px; font-weight:700; letter-spacing:-.02em; margin-top:10px; }
.vsub { font-size:13.5px; color:var(--ink-soft); margin-top:8px; }
.vloc { display:flex; align-items:center; gap:4px; font-size:12px; color:var(--ink-faint); margin-top:9px; }
.vloc svg { flex:none; width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:1.6; }
.vbio { font-size:14px; color:var(--ink); line-height:1.5; margin-top:13px; }
/* SERVIÇOS on the vitrine (s58): the ✂ block. Small-radius TAGS (label shape, not a pill), so a
   non-interactive service label never reads as a tappable chip. */
.vsvc { margin-top:20px; padding-top:18px; border-top:1px solid var(--hair); }
.vsvc-h { display:flex; align-items:center; gap:7px; font-size:11.5px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--ink-faint); margin:0 0 12px; }
.vsvc-i { flex:none; width:15px; height:15px; fill:none; stroke:var(--dot); stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; }
.vsvc-tags { display:flex; flex-wrap:wrap; gap:7px 8px; }
.vsvc-tag { font-size:13px; font-weight:500; color:var(--ink-soft); background:var(--tint); border-radius:5px; padding:5px 10px; }
/* Editar vitrine (s50): the two lines as quiet edits, in their own dress, dashed until tapped */
.vqedit-form { position:relative; }
.vqedit-form .inline-saved { position:absolute; top:-2px; right:0; margin:0; }
/* NOT '.vq' — the ficha's quiet value cells already wear that name (s50 regression) */
.vqedit { border-color:transparent; }   /* quiet until tapped (s50): text at rest, a line on focus */
/* s78 (his call): on focus the field becomes a real input like the Perfil ones — bigger TEXT
   (16px) with generous breathing room, on the brighter --field cream every other text input uses.
   The room comes from SYMMETRIC padding (not a min-height floor), so the text stays vertically
   centred — a min-height taller than the content left the extra space below the top-aligned text.
   Presentation (small text, flush, no box) is untouched; the auto-grow sizes the box to content. */
.vqedit:focus { border-color:var(--accent); background:var(--field); font-size:16px; padding:16px 14px; }
.vqedit-sub { font-size:13.5px; color:var(--ink-soft); margin-top:8px; }
.vqedit-bio { font-size:14px; line-height:1.5; margin-top:13px; }
.vbody .wabtn { display:flex; justify-content:center; width:100%; margin-top:14px; }
.vgrid { display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px 5px; padding:22px 20px 30px; }
.vcell { width:100%; aspect-ratio:2/3; border-radius:var(--r-card); overflow:hidden; background:var(--paper-2); display:grid; place-items:center; min-height:0; }
.vcell img { width:100%; height:100%; object-fit:cover; }
.vcell svg { width:40%; height:40%; opacity:.35; }
/* The resting-grid tile = the ACERVO CARD idiom (s45, his pick — image + a centred
   size footer as ONE lifted card, .acervo .tile's exact shape). The 2:3 aspect lives
   on the IMAGE BOX itself — the engine-proof shape; the %-height chain it replaces
   banded photos shorter than 2:3 on iOS WebKit (Chromium resolved it: false green). */
.vlink { display:flex; flex-direction:column; gap:0; min-width:0; height:100%;
  text-decoration:none; color:inherit; background:var(--card);
  border-radius:var(--r-card); overflow:hidden; box-shadow:0 8px 22px var(--shadow-strong); }
.vlink .vcell { border-radius:0; background:var(--card); }
.vcap { text-align:center; padding:7px 8px 8px; font-size:11.5px; color:var(--ink-faint);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* ---- Vitrine curated front (vitrine-arc, s34) ---- */
/* Feature mosaic: the capa spans 2×2 among the 3-col grid. Small tiles keep the 2:3
   portrait that sets the row height; the capa (2 cols × 2 rows) reads as the same
   portrait ratio at double scale — one piece lifted, still image-model-faithful. */
.vgrid.mgrid > .vtile.feat { grid-column:span 2; grid-row:span 2; aspect-ratio:auto; }
.vgrid.mgrid > .vtile.feat .vcell { aspect-ratio:auto; flex:1; min-height:0; position:relative; }
.vgrid.mgrid > .vtile.feat .vcell img { position:absolute; inset:0; width:100%; height:100%; }
/* The door: "ver acervo completo" (loja) / "editar destaques" (own vitrine). */
.vdoor { display:flex; align-items:center; justify-content:center; gap:8px; margin:6px 20px 30px;
  padding:13px; border-radius:var(--r-ctl); background:var(--paper-2); border:1px solid var(--line-2);
  color:var(--ink); font-size:14px; font-weight:600; text-decoration:none; }
.vdoor .n { color:var(--ink-soft); font-weight:500; }
.vdoor svg { width:15px; height:15px; stroke:var(--ink-soft); fill:none; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; }
.vdoor:active { background:var(--paper); }
.vbacklink { display:inline-flex; align-items:center; gap:5px; margin:14px 20px 0;
  font-size:13px; color:var(--ink-soft); text-decoration:none; }
.vbacklink svg { width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:1.8; }
.curhint { font-size:12.5px; color:var(--ink-soft); line-height:1.45; margin:6px 20px 2px; }
/* Curation lives in the COVER chrome (vitrine-arc), never on the pieces — so the plain
   vitrine stays an exact mirror of the loja. This is the deliberate edit entry. */
.vcoveredit { position:absolute; top:14px; right:12px; display:inline-flex; align-items:center;
  gap:5px; background:rgba(22,18,28,.5); color:#fff; font-size:13px; padding:6px 11px;
  border-radius:var(--r-pill); text-decoration:none; }
.vcoveredit svg { width:15px; height:15px; stroke:#fff; fill:none; stroke-width:1.8; }
.vcoveredit.done { background:var(--accent); color:var(--on-accent); font-weight:600; }
.curhint { font-size:12.5px; color:var(--ink-soft); line-height:1.45; margin:12px 20px 4px; }
.curhint.warn { color:var(--danger); font-weight:600; }
.impwarn { color:#b8503f; font-weight:600; margin-top:10px; }
/* ---- Rental piece pick-mode (vitrine-arc): the acervo IS the picker ---- */
.pickhead { display:flex; align-items:center; gap:6px; }
.pickhead .pickback { display:grid; place-items:center; width:34px; height:34px; margin-left:-6px; color:var(--ink-soft); text-decoration:none; }
.pickhead .pickback svg { width:22px; height:22px; stroke:currentColor; fill:none; stroke-width:1.8; }
.tilewrap.pickable { cursor:pointer; -webkit-tap-highlight-color:transparent; }
.tilewrap.pickable .img { transition:opacity .12s; }
.tilewrap.pickable:not(.picked) .img { opacity:.6; }
.tilewrap.pickable.picked .img { outline:2px solid var(--accent); outline-offset:-2px; }
.pickcheck { position:absolute; top:6px; right:6px; width:24px; height:24px; border-radius:50%;
  background:var(--accent); display:grid; place-items:center; opacity:0; z-index:3; pointer-events:none;
  box-shadow:0 1px 5px rgba(20,16,10,.3); }
.pickcheck svg { width:14px; height:14px; stroke:var(--on-accent); fill:none; stroke-width:2.6;
  stroke-linecap:round; stroke-linejoin:round; }
.tilewrap.pickable.picked .pickcheck { opacity:1; }
/* Inspect in pick-mode (s41): the eye, top-left (opposite the select check). Tap opens
   the ficha to look close before adding — the capability pick-mode used to drop. Its own
   tap target, above the tile, so app.js lets it through instead of toggling select. */
.pickpeek { position:absolute; top:6px; left:6px; width:26px; height:26px; border-radius:50%;
  background:rgba(20,16,10,.42); -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  display:grid; place-items:center; z-index:4; text-decoration:none;
  -webkit-tap-highlight-color:transparent; }
.pickpeek svg { width:15px; height:15px; stroke:#fff; fill:none; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; }
.pickpeek:active { background:rgba(20,16,10,.6); }
.picksave { position:sticky; bottom:0; z-index:20; display:flex; justify-content:center;
  padding:12px 20px calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(to top, var(--bg) 62%, transparent); }
.picksave-go { width:100%; max-width:400px; padding:14px; border:none; border-radius:12px;
  background:var(--accent); color:var(--on-accent); font-size:15px; font-weight:600; cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.picksave-go:active { filter:brightness(.94); }
.ripick { display:flex; align-items:center; justify-content:center; gap:8px; margin:10px 0 4px;
  padding:12px; border-radius:12px; background:var(--paper-2); border:1px solid var(--line-2);
  color:var(--ink); font-size:14px; font-weight:600; text-decoration:none; }
.ripick svg { width:17px; height:17px; stroke:currentColor; fill:none; stroke-width:1.7; }
/* Edit mode: the whole tile is an INVISIBLE pin (like the mesa's throw-zone). Unpinned
   tiles dim back; a pinned one lights up and wears a quiet check; the capa wears a star.
   No pills anywhere — the chosen pieces simply glow. */
.vgrid-edit .editile { cursor:pointer; -webkit-tap-highlight-color:transparent; }
.vgrid-edit .editile .vcell { transition:opacity .12s; }
.vgrid-edit .editile.pinned .vcell { opacity:.45; }   /* already in the vitrine (s50): dimmed, with the check */
.vpinbadge { position:absolute; top:5px; right:5px; width:22px; height:22px; border-radius:50%;
  background:var(--accent); display:grid; place-items:center; opacity:0; z-index:3;
  pointer-events:none; box-shadow:0 1px 5px rgba(20,16,10,.3); }
.vpinbadge svg { width:13px; height:13px; stroke:var(--on-accent); fill:none; stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round; }
.editile.pinned .vpinbadge { opacity:1; }
/* THE MIRROR IS THE EDITOR (s50): the public mosaic with editable quadros. The capa
   is the 2×2 (.feat follows the first slot); empties are 'escolher' outlines. */
.vgrid.mgrid > .feat { grid-column:span 2; grid-row:span 2; aspect-ratio:auto; }
/* THE SLOT GRAMMAR (s83, his call): a FILLED quadro looks exactly like the mirror's card
   (same 16px card, no frame) — editing must not stop the page looking like her vitrine. The
   dashed 'toque pra definir' outline is ONLY for an empty quadro ('escolher'); a filled card
   wearing it was a mixed signal, and its 6px photo inside a 16px frame never nested (s50). */
.vslot { position:relative; cursor:pointer; -webkit-tap-highlight-color:transparent; border-radius:var(--r-card);
  -webkit-touch-callout:none; -webkit-user-select:none; user-select:none; }
.vslot img { -webkit-touch-callout:none; -webkit-user-drag:none; }
.vslot.vtile { transition:box-shadow .15s; }
.vslot .vcell { border-radius:var(--r-card); background:var(--card); overflow:hidden; }
.vslot.feat .vcell { aspect-ratio:auto; height:100%; position:relative; }
.vslot.feat .vcell img { position:absolute; inset:0; width:100%; height:100%; }
.vslot.empty { border:1.5px dashed var(--line-2); }
/* hold-to-lift (s83): the held card rises and follows the finger (JS sets the translate);
   the quadro under the finger is the drop target. Nothing like the hold-DELETE ring. */
.vslot.lifted { z-index:30; box-shadow:0 14px 30px var(--shadow-strong); transition:none; pointer-events:none; }
.vslot.droptarget .vcell { outline:2px solid var(--accent); outline-offset:2px; }
.vslot.empty.droptarget { border-color:var(--accent); }
.vcue { margin:0; font-size:12px; color:var(--ink-faint); line-height:1.3; }
.vslot.empty { padding:0; display:grid; place-items:center; color:var(--ink-faint); font-size:12px; aspect-ratio:2/3; }
.vlayout { display:flex; justify-content:space-between; align-items:center; gap:10px; padding:16px 20px 0; margin-bottom:-12px; }
.vlayout-seg { width:auto; }
.vlayout-opt { padding:8px 12px; border:none; background:none; font:inherit; color:var(--ink-faint); border-left:1px solid var(--line); cursor:pointer; }
.vlayout-opt:first-child { border-left:none; }
.vlayout-opt svg { width:18px; height:16px; display:block; fill:currentColor; }
.vlayout-opt.on { background:var(--accent); color:var(--on-accent); }
.vslot.empty.feat { aspect-ratio:auto; font-size:13px; }
.vseednote { font-size:12.5px; color:var(--ink-soft); line-height:1.4; margin:16px 20px -10px; }
.vpick .pash-panel { max-height:88vh; display:flex; flex-direction:column; }
.vpick-ttl { font-size:18px; font-weight:800; letter-spacing:-.01em; padding:4px 12px 0; }
/* s83: the piece being replaced, in the header — a small card + 'No lugar de' + its name. Its
   own row, outside the options grid, so it reads as the reference, never as a choice. */
.vpick-anchor { display:flex; align-items:center; gap:12px; padding:4px 12px 2px; }
.vpick-anchor[hidden] { display:none; }
.vpick-thumb { flex:none; width:44px; aspect-ratio:2/3; border-radius:8px; overflow:hidden; background:var(--card); }
.vpick-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.vpick-atxt { min-width:0; display:flex; flex-direction:column; gap:1px; }
.vpick-atxt small { font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); }
.vpick-atxt b { font-size:17px; font-weight:800; letter-spacing:-.01em; line-height:1.2;
  overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.vpick .vsrc { margin:14px 0 4px; }
.vpick-scroll { flex:1; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.vpick .vsrc-chips { padding:8px 0 2px; margin:0 0 6px; }
.vpick .vgrid { padding:10px 0 16px; }
.vpick-remove { margin-top:4px; }
.vpick-remove[hidden] { display:none; }
.vsrc { margin:8px 20px 10px; }
.vsrc .qhome-x.hidden { display:none; }
.vsrc-chips { display:flex; gap:6px; overflow-x:auto; padding:0 20px 2px; margin:0 0 8px;
  -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.vsrc-chips::-webkit-scrollbar { display:none; }
.vsrc-chip { flex:0 0 auto; border:1px solid var(--line-2); background:var(--paper);
  border-radius:999px; padding:6px 13px; font-family:var(--sans); font-size:13px;
  color:var(--ink-soft); white-space:nowrap; cursor:pointer; -webkit-appearance:none; appearance:none; }
.vsrc-chip.on { background:var(--accent); border-color:var(--accent); color:var(--on-accent); font-weight:600; }
.vsrc-colors { padding:0 20px; margin:0 0 12px; }
.vsrc-colors .csw { -webkit-appearance:none; appearance:none; padding:0; cursor:pointer; }
.vsrch-empty .linklike { background:none; border:none; padding:0; font:inherit; color:var(--accent);
  font-weight:600; cursor:pointer; -webkit-appearance:none; appearance:none; }
/* Batch pin (s33) note, superseded s45: the tile no longer owns the aspect — the
   CARD is content-sized (2:3 image box + conditional footer), exactly like the
   acervo grid; the composer's plain editile keeps its box from the base .vcell. */
/* vitrine empty state — a padded, centred block (the page is .nopad, so a bare
   paragraph would run edge-to-edge) */
.vempty { padding:38px 28px 52px; text-align:center; }
.vempty svg { width:38px; height:38px; display:block; margin:0 auto 14px; fill:none; stroke:var(--line-2); stroke-width:2; }
.vempty p { font-size:14px; color:var(--ink-soft); line-height:1.6; max-width:300px; margin:0 auto; }
.vempty b { color:var(--ink); font-weight:600; white-space:nowrap; }

/* ============================================================
   TRABALHOS — the engagement funnel (#18). One unified list over
   produção · locação · orçamento, sliced by TYPE (the card face,
   already the .wcard idiom) and STATE (the group bands, actionable
   first). Orçamento is the entry state, not a sibling section.
   ============================================================ */
.engtop { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:8px 2px 0; }
.engtop h1 { font-size:26px; font-weight:800; letter-spacing:-.025em; }
.engadd { flex:none; display:inline-flex; align-items:center; gap:5px; font-size:12.5px; font-weight:600;
  color:var(--accent); border:1px solid var(--line-2); background:#fff; border-radius:2px; padding:7px 11px;
  cursor:pointer; text-decoration:none; }
.engadd:active { background:var(--paper-2); }
.engadd svg { width:14px; height:14px; stroke:currentColor; stroke-width:2; fill:none; }

/* Direction tabs (s44) — the funnel's primary segmentation, retiring the type chips:
   a figurinista sorts by which way work flows (Saindo / Entrando), not by object type.
   A quiet two-up segmented control; the active tab firms to ink, the rest recede. */
.dtabs { display:flex; gap:6px; margin:16px 2px 12px; }
.dtab { flex:1; display:inline-flex; align-items:center; justify-content:center; gap:7px;
  font-size:13px; padding:9px 8px; border-radius:12px; border:1px solid var(--line);
  background:#fff; color:var(--ink-soft); cursor:pointer; font-family:inherit; }
.dtab svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.9; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.dtab.on { border-color:var(--ink); color:var(--ink); font-weight:600; }
.dcnt { font-size:11.5px; color:var(--ink-faint); font-weight:600; }
.dtab.on .dcnt { color:var(--ink-soft); }
.lanehint { font-size:12px; color:var(--ink-faint); margin:0 4px; }
.lane[hidden] { display:none; }

.enggrp { font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-soft);
  font-weight:700; margin:20px 2px 9px; display:flex; align-items:center; gap:7px; }
.enggrp small { font-weight:600; color:var(--ink-faint); letter-spacing:.02em; text-transform:none; font-size:11px; }
/* Status colour on the section header (s41) — the ONE colour axis. A leading dot +
   coloured label: amber "Precisa de você" (act), green "Em andamento" (live); the
   pipeline + encerrado stay muted. */
.enggrp.act { color:var(--warn); }
.enggrp.live { color:var(--ok); }
.enggrp.act::before, .enggrp.live::before { content:""; flex:none; width:6px; height:6px;
  border-radius:50%; background:currentColor; }

/* proposta face — tentative, not-yet-real work reads pre-attentively as a dashed card */
.wcard.prop { border-style:dashed; border-color:var(--line-2); background:var(--card); }
.cardeyebrow.net { display:inline-flex; align-items:center; gap:5px; text-transform:none; letter-spacing:.02em; }
.cardeyebrow.net svg { width:13px; height:13px; stroke:currentColor; stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.wcard.done { opacity:.82; }

/* encerrado — a single collapsed row (native <details>), so 14 closed jobs never dominate */
.engclosed { margin-top:2px; }
.engclosed > summary { list-style:none; display:flex; align-items:center; justify-content:space-between;
  padding:13px 16px; border:1px solid var(--line); border-radius:15px; background:transparent;
  color:var(--ink-soft); font-size:13.5px; cursor:pointer; }
.engclosed > summary::-webkit-details-marker { display:none; }
.engclosed > summary b { font-weight:700; color:var(--ink); }
.engclosed > summary svg { width:16px; height:16px; stroke:var(--ink-faint); stroke-width:1.8; fill:none; transition:transform .18s; }
.engclosed[open] > summary svg { transform:rotate(90deg); }
.engclosed[open] > summary { margin-bottom:12px; }

.engempty { text-align:center; color:var(--ink-soft); padding:40px 20px; }
.engempty p { font-size:14px; line-height:1.5; }

/* fork sheet — ＋ Novo trabalho: orçamento leads (the funnel), locação/produção
   for work that arrives already confirmed. Replaces the three scattered + buttons. */
.forksheet { position:fixed; inset:0; z-index:95; display:none; }
.forksheet.on { display:block; }
.forksheet-back { position:absolute; inset:0; background:rgba(40,28,48,.38); }
.forksheet-panel { position:absolute; left:0; right:0; bottom:0; background:var(--paper);
  border-radius:22px 22px 0 0; padding:18px 18px calc(26px + env(safe-area-inset-bottom));
  box-shadow:0 -8px 30px rgba(40,28,48,.18); max-width:640px; margin:0 auto; }
.forksheet-panel h4 { font-size:15px; font-weight:700; margin:2px 2px 12px; }
.forkopt { display:flex; align-items:center; gap:13px; padding:13px 12px; border:1px solid var(--line);
  border-radius:12px; margin-top:8px; background:var(--card); text-decoration:none; color:var(--ink);
  width:100%; text-align:left; font-family:var(--sans); font-size:inherit; cursor:pointer; }
.forkopt:active { background:var(--paper-2); }
.forkopt.lead { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset; }
.forkopt .ic { flex:none; width:38px; height:38px; border-radius:10px; background:var(--paper-2); display:grid; place-items:center; }
.forkopt .ic svg { width:20px; height:20px; stroke:var(--accent); stroke-width:1.7; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.forkopt b { display:block; font-size:14.5px; font-weight:700; }
.forkopt small { display:block; font-size:12px; color:var(--ink-soft); margin-top:1px; line-height:1.35; }
.forkcancel { display:block; text-align:center; font-size:14px; color:var(--ink-soft); margin-top:14px;
  background:none; border:none; width:100%; padding:6px; cursor:pointer; }
/* Produção-pelo-roteiro intake (s22): the picker row + the FAB-world progress sheet. */
.forkopt#prodRoteiro { position:relative; overflow:hidden; }
.forkopt#prodRoteiro input[type=file] { position:absolute; inset:0; opacity:0; cursor:pointer; }
.forkopt-sub { display:block; text-align:center; font-size:12.5px; color:var(--accent); text-decoration:none;
  margin-top:6px; padding:8px; }
.prodprog-stage { display:flex; align-items:center; gap:8px; font-size:15px; font-weight:600; color:var(--ink); padding:6px 2px; }
.prodprog-live .notes { margin-top:6px; }
.prodprog-err .decu-warn { margin:2px 0 12px; }

/* ============================================================
   TODAY INBOX (#22) — one urgency-ordered feed of everything
   actionable, each item tagged by source. Overdue leads (the tint
   is the pre-attentive signal); the quick task-adder sits above.
   ============================================================ */
/* s45 inbox-feel: band items are CARDS that arrived, not rows in a table — each one
   openable, each one leaves when answered. A pedido (a true arrival) wears the accent
   edge; clock items stay quieter. */
.inbox { display:flex; flex-direction:column; gap:8px; margin-top:14px; }
.inbox-item { display:flex; align-items:center; gap:12px; padding:13px 14px; text-decoration:none;
  color:var(--ink); background:var(--card); border:1px solid var(--line); border-radius:12px; }
.inbox-item:has(.inbox-ic.pedido), .inbox-item:has(.inbox-urg.warn) {
  border-color:color-mix(in srgb, var(--accent) 35%, var(--line)); }
a.inbox-item:active { background:var(--paper-2); }
.inbox-item.nolink { cursor:default; }
/* derived cards wrap their tap-face so a dismiss × can sit outside the link (#28) */
.inbox-face { flex:1; min-width:0; display:flex; align-items:center; gap:12px; text-decoration:none; color:inherit; }
.inbox-face:active { background:var(--paper-2); }
.inbox-face.nolink { cursor:default; }
.inbox-item.withx { gap:6px; }
.inbox-thumb { flex:none; width:44px; height:54px; border-radius:4px; overflow:hidden; background:var(--paper-2); }
.inbox-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.inbox-ic { flex:none; width:44px; height:44px; border-radius:50%; display:grid; place-items:center;
  background:var(--paper-2); color:var(--accent); }
.inbox-ic svg { width:21px; height:21px; fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; }
.inbox-ic.retorno { color:var(--terra); }
.inbox-ic.cliente { color:var(--brick); }
.inbox-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.inbox-src { font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint); font-weight:600; }
/* the event line is the card's payload (s45) — it wraps, never truncates; the
   subtitle gets two lines before it ellipsizes (who + what must survive) */
.inbox-title { font-size:15px; font-weight:600; line-height:1.25; }
.inbox-sub { font-size:12.5px; color:var(--ink-soft); line-height:1.3; overflow:hidden;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.inbox-right { flex:none; display:flex; align-items:center; gap:8px; }
.inbox-urg { flex:none; font-size:10.5px; padding:3px 9px; border-radius:20px; white-space:nowrap;
  background:var(--paper-2); color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.inbox-urg.alert { background:#F2DCD5; color:#A2402C; }
.inbox-urg.warn { background:#F4E7CE; color:#8A5E14; }
.inbox-urg.ok { background:#E4EDE1; color:#36593A; }
.inbox-urg.muted { background:var(--paper-2); color:var(--ink-faint); }
.inbox-wa { flex:none; width:34px; height:34px; border-radius:50%; border:1px solid var(--line-2);
  display:grid; place-items:center; color:var(--accent); }
.inbox-wa svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.6; }
.inbox-item.tarefa { gap:11px; }
.inbox-item.tarefa .inbox-title { font-weight:500; white-space:normal; }
.inbox-item.tarefa.overdue .inbox-title { color:var(--red); }
.inboxzero { margin:14px 2px 4px; font-size:13px; color:var(--ink-faint); }
.inbox-empty { text-align:center; color:var(--ink-soft); padding:44px 20px; }
.inbox-empty p { font-size:14px; line-height:1.5; }

/* next-step nudge (#2) — one quiet, contextual line that points at the funnel's
   next move (capture the next piece · build the first look). Dismissable, never
   more than one per surface. */
.nextnudge { display:flex; align-items:center; gap:12px; margin:14px 0 6px; padding:12px 14px;
  border:1px solid var(--line-2); border-radius:12px; background:var(--sand); text-decoration:none; color:var(--ink); }
.nextnudge:active { background:var(--paper-2); }
.nextnudge-link { flex:1; min-width:0; display:flex; align-items:center; gap:12px; text-decoration:none; color:inherit; }
.nextnudge-ic { flex:none; width:34px; height:34px; border-radius:var(--r-ctl); background:#fff; display:grid; place-items:center; color:var(--accent); }
.nextnudge-ic svg { width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
.nextnudge-body { flex:1; min-width:0; font-size:13.5px; color:var(--ink-soft); line-height:1.35; }
.nextnudge-body b { font-weight:700; color:var(--ink); }
.nextnudge-go { flex:none; font-size:18px; font-weight:700; color:var(--accent); }
.nextnudge-x { flex:none; background:none; border:none; color:var(--ink-faint); font-size:20px; line-height:1; cursor:pointer; padding:2px 4px; }

/* orçamento decision banner (#3) on the owner editor */
.decibanner { display:flex; align-items:flex-start; gap:12px; margin:14px 0 4px; padding:13px 15px;
  border-radius:12px; border:1px solid var(--line-2); }
.decibanner.ok { background:#E4EDE1; border-color:#CBDCD2; }
.decibanner.warn { background:#F4E7CE; border-color:#E4D2A8; }
.decibody { flex:1; min-width:0; }
.decibody b { display:block; font-size:14.5px; font-weight:700; color:var(--ink); }
.decibody span { display:block; font-size:12.5px; color:var(--ink-soft); margin-top:2px; }
.decibody .decimsg { font-style:italic; color:var(--ink); }
.decidismiss { flex:none; background:none; border:none; color:var(--ink-soft); font-family:var(--sans);
  font-size:12px; text-decoration:underline; cursor:pointer; padding:2px 0; }

/* ============================================================
   ASYNC AI RENDER (#7) — a "generating" pill while the OpenAI call
   runs in the background, and a tappable "ready" banner when it
   lands. Non-interrupting: the user keeps working, taps when ready.
   ============================================================ */
/* capture session (#43) — the eager-upload overlay: shoot, next, shoot; concluir → revisar */
.capsession[hidden] { display:none; }
.capsession { position:fixed; inset:0; z-index:96; display:flex; align-items:flex-end;
  background:rgba(20,16,10,.42); }
.capsession-panel { width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:18px 18px 0 0; padding:18px 18px calc(18px + env(safe-area-inset-bottom));
  box-shadow:0 -12px 40px rgba(20,16,10,.25); }
.capsession-head { display:flex; align-items:baseline; justify-content:space-between; }
/* onde guarda? (s50): one quiet row under the head, the place of the whole session */
.capsession-where { display:flex; align-items:center; gap:10px; margin:8px 0 2px; font-size:13px; color:var(--ink-soft); }
.capsession-where input { flex:1; min-width:0; border:1px solid var(--line); border-radius:10px; padding:7px 10px; font:inherit; font-size:14px; color:var(--ink); background:var(--paper); }
.capsession-where input:focus { outline:none; border-color:var(--accent); }
.optrow.optother { color:var(--accent); font-weight:600; }
.capsession-head b { font-family:var(--serif); font-size:19px; letter-spacing:-.01em; }
.capsession-head span { font-size:13px; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.capsession-chips { display:flex; flex-wrap:wrap; gap:7px; margin:12px 0 4px; min-height:8px; }
.capchip { border:none; font-family:var(--sans); font-size:12px; font-weight:600; padding:6px 12px;
  border-radius:16px; background:var(--paper-2); color:var(--ink-soft); }
.capchip-x { display:inline-block; margin-left:8px; padding:0 4px; font-size:15px; line-height:1; color:var(--ink-faint); }   /* s70: discard the draft from its chip */
.capchip-x:active { color:var(--danger); }
.capchip.sending { color:var(--ink-faint); animation:genpulse 1.2s ease-in-out infinite; }
.capchip.ok { background:color-mix(in srgb, var(--ok) 14%, transparent); color:var(--ok); }
.capchip.fail { background:color-mix(in srgb, var(--danger) 12%, transparent); color:var(--danger); cursor:pointer; }
.capsession-next { position:relative; display:flex; align-items:center; justify-content:center;
  gap:9px; margin-top:12px; background:var(--accent); color:var(--on-accent); border-radius:12px;
  padding:16px; font-size:16px; font-weight:700; cursor:pointer; }
.capsession-next[hidden] { display:none; }
.capsession-next svg { width:21px; height:21px; stroke:currentColor; stroke-width:1.7; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.capsession-next input { position:absolute; inset:0; width:100%; height:100%; margin:0; padding:0;
  border:0; opacity:0; cursor:pointer; -webkit-appearance:none; appearance:none; font-size:16px; }
.capsession-adds[hidden] { display:none; }
.capsession-adds { display:flex; gap:8px; margin-top:8px; }
.capsession-more { position:relative; flex:1; display:flex; align-items:center; justify-content:center;
  gap:7px; border:1px solid var(--accent); background:var(--paper); color:var(--accent);
  border-radius:12px; padding:12px 8px; font-size:14px; font-weight:600; cursor:pointer; }
.capsession-more[hidden] { display:none; }
.capsession-more svg { width:17px; height:17px; stroke:currentColor; stroke-width:2; fill:none; stroke-linecap:round; }
.capsession-more input { position:absolute; inset:0; width:100%; height:100%; margin:0; padding:0;
  border:0; opacity:0; cursor:pointer; -webkit-appearance:none; appearance:none; font-size:16px; }
.capsession-done { display:block; width:100%; margin-top:8px; border:1px solid var(--line-2);
  background:var(--paper); color:var(--ink); border-radius:12px; padding:13px;
  font-family:var(--sans); font-size:14.5px; font-weight:600; cursor:pointer; }
.capsession-done:disabled { opacity:.5; }
/* s70 (his call): 'Enviando…' breathes — the sheet's ONE visible wait, on the exit button */
.capsession-done.sending { animation:vxt-pulse 1.4s ease-in-out infinite; }
.capsession-cap { font-size:12.5px; color:var(--terra); text-align:center; margin:10px 0 0; }
.capsession-hint[hidden] { display:none; }
.capsession-hint { font-size:12px; color:var(--ink-soft); text-align:center; margin:8px 4px 0; line-height:1.35; }
/* Quicklog session (s14) — the same bottom-sheet door as the capsession, with price
   rows. Reuses .qlrow/.qlthumb/.qlprice from the (now-deleted) quicklog page. */
.qlsession[hidden] { display:none; }
.qlsession { position:fixed; inset:0; z-index:96; display:flex; align-items:flex-end; background:rgba(20,16,10,.42); }
.qlsession-panel { width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:18px 18px 0 0; padding:18px 18px calc(18px + env(safe-area-inset-bottom));
  box-shadow:0 -12px 40px rgba(20,16,10,.25); max-height:86vh; overflow-y:auto; }
.qlsession-head { display:flex; align-items:baseline; justify-content:space-between; margin-bottom:12px; }
.qlsession-head b { font-family:var(--serif); font-size:19px; letter-spacing:-.01em; }
.qlsession-head span { font-size:13px; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.qlrows { display:flex; flex-direction:column; gap:8px; margin-bottom:10px; }
.qlrow.sending { opacity:1; }   /* s70 (his call): the row reads as done from the first frame — the photo is
                                   hers, the price is typable; only Concluir carries the wait */
.qlrow.fail { border-color:var(--danger); }
.qlsession .qlbulk { margin:0 0 10px; }
.qlsession .qlhint { margin:0 2px 10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }   /* one row, never an orphan */
.revhint { margin:12px 2px 10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:left; }   /* left under the eyebrow (s80) */
.qlsession .capsession-next, .qlsession .capsession-done { margin-top:0; }
.qlsession .capsession-done { margin-top:8px; }

.renderbar[hidden] { display:none; }
/* The RENDER bar carries outcomes only now (s59) — its pink 'gerando' state was dropped
   (redundant with the in-context beat; polished design parked in docs/parked-gerando-bar.md).
   But .renderbar.gen still dresses the DECUPAGEM banner (#decubar, Studio) 'Lendo o roteiro…':
   a quiet paper pill with a soft pulsing dot. genpulse also drives .capchip.sending. */
.renderbar.gen { pointer-events:none; background:var(--paper); color:var(--ink-soft);
  border:1px solid var(--line-2); box-shadow:0 6px 20px -10px rgba(60,50,35,.25); }
.renderbar.gen .renderbar-main::before { content:""; width:9px; height:9px; border-radius:50%;
  background:var(--accent); animation:genpulse 1.2s ease-in-out infinite; }
@keyframes genpulse { 0%,100% { opacity:.35; transform:scale(.8);} 50% { opacity:1; transform:scale(1);} }
/* Compact + centered (s59): 'gerando' and 'pronto' hug their content and sit centered
   instead of straddling the whole width — each is a short status pill, not a full bar. */
.renderbar { position:fixed; left:50%; transform:translateX(-50%); bottom:130px; z-index:91;
  width:max-content; max-width:calc(100% - 24px); margin:0;
  display:flex; align-items:center; background:var(--ink); color:var(--paper); border-radius:14px;
  box-shadow:0 10px 30px -8px rgba(40,28,48,.5); overflow:hidden; }
/* err (s59): a failed prova is a heads-up, not an alarm — the calm AMBER status family,
   capped and centered (not a full-bleed red slab), a smaller multi-line message, quiet ×. */
.renderbar.err { background:var(--chip-warn-bg); color:var(--chip-warn-ink);
  width:322px; max-width:calc(100% - 24px); align-items:flex-start; box-shadow:0 6px 20px -12px var(--shadow); }
.renderbar.err .renderbar-main { font-size:12.5px; font-weight:500; line-height:1.45; padding:11px 14px; }
.renderbar.err .renderbar-main b { font-weight:600; }
.renderbar.err .renderbar-x { color:var(--chip-warn-ink); opacity:.55; padding:11px 12px; }
/* Ambient expiry banner (s41): in-flow at the very top so it pushes content down instead
   of obscuring a bottom CTA; calm amber (a STATUS, not a red alarm); safe-area aware. */
.expiredbar { display:flex; align-items:center; gap:10px;
  margin:calc(env(safe-area-inset-top, 0px) + 10px) 12px 4px; padding:11px 12px;
  border-radius:14px; background:var(--chip-warn-bg); color:var(--chip-warn-ink); }
.expiredbar-lock { flex:none; width:26px; height:26px; border-radius:50%;
  background:var(--chip-warn-ink); display:grid; place-items:center; }
.expiredbar-lock svg { width:14px; height:14px; fill:none; stroke:var(--chip-warn-bg);
  stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.expiredbar-txt { flex:1; min-width:0; font-size:12.5px; line-height:1.38; }
.expiredbar-txt b { font-weight:600; }
.expiredbar-cta { flex:none; font-size:13px; font-weight:600; color:var(--on-accent);
  background:var(--accent); border-radius:20px; padding:8px 15px; text-decoration:none;
  border:none; font-family:inherit; cursor:pointer; -webkit-appearance:none; appearance:none; }
.expiredbar-cta:active { background:var(--accent-press); }
/* Dismiss (s41): tertiary, subordinate to Renovar — a small faint × so it reads as
   "not now", never competing with the CTA. Deliberate tap target, no mis-fire. */
.expiredbar-x { flex:none; width:26px; height:26px; margin:-4px -2px -4px 0; border:none;
  background:none; color:var(--chip-warn-ink); opacity:.55; font-size:19px; line-height:1;
  cursor:pointer; -webkit-appearance:none; appearance:none; }
.expiredbar-x:active { opacity:1; }
/* Access gate (s41): the amber lock is the ONE learnable mark of an expired account —
   it rides every gated control (AI renders, dictation mics, create doors), always over
   a dimmed control, and tapping any of them opens the renew sheet (app.js decorates +
   intercepts). The banner is the one place with words; the locks are its silent echoes.
   Distinct from the NEUTRAL privacy lock by the amber + the dimmed state (dim is the
   colourblind-safe cue). #fbMic ("falar com a gente") is exempt — never gated. */
/* NOTE: .gated must NOT set `position` — it would tie/override a control that is
   already positioned (e.g. .herospark's own position:absolute, same specificity)
   and knock it out of place. app.js instead sets position:relative inline ONLY on
   controls whose computed position is static, so the scrim/lock get a containing
   block without disturbing already-positioned overlays. */
.gatescrim { position:absolute; inset:0; border-radius:inherit; background:var(--paper);
  opacity:.5; pointer-events:none; z-index:3; }
.gatelock { position:absolute; top:-5px; right:-5px; width:20px; height:20px; border-radius:50%;
  background:var(--chip-warn-bg); display:grid; place-items:center; pointer-events:none;
  z-index:4; box-shadow:0 1px 3px var(--shadow); }
.gatelock svg { width:11px; height:11px; fill:none; stroke:var(--chip-warn-ink);
  stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
/* Icon-only round gated buttons (the hero "Polir com IA" spark, dictation mics) can't
   wear a corner badge — it pokes outside an overflow:hidden photo/tile and clips, and a
   paper scrim over their own fill just muddies them. The button BECOMES the lock: its
   glyph hides, the scrim drops, the fill goes amber, the lock centres. */
.herospark.gated, .fieldmic.gated { background:var(--chip-warn-bg); }
.herospark.gated > svg, .fieldmic.gated > svg { opacity:0; }
.herospark.gated > .gatescrim, .fieldmic.gated > .gatescrim { display:none; }
.herospark.gated > .gatelock, .fieldmic.gated > .gatelock { top:50%; left:50%; right:auto;
  transform:translate(-50%, -50%); width:auto; height:auto; background:none; box-shadow:none; }
.herospark.gated > .gatelock svg { width:22px; height:22px; }
.fieldmic.gated > .gatelock svg { width:17px; height:17px; }
body.decubar-on #renderbar { bottom:188px; }
/* .renderbar-ic / -x set display:grid, which overrides the [hidden] attribute — so drive
   their visibility from the bar's state: the decupagem 'Lendo…' (gen) hides both; an error
   bar hides the check but keeps the × (to dismiss). */
.renderbar.gen .renderbar-ic, .renderbar.gen .renderbar-x, .renderbar.err .renderbar-ic { display:none; }
.renderbar-main { flex:1; display:flex; align-items:center; gap:11px; padding:14px 16px;
  text-decoration:none; color:inherit; font-size:14.5px; font-weight:600; }
.renderbar-ic { flex:none; width:26px; height:26px; border-radius:50%; background:var(--accent);
  display:grid; place-items:center; }
.renderbar-ic svg { width:15px; height:15px; fill:none; stroke:#fff; stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round; }
.renderbar-x { flex:none; background:none; border:none; color:rgba(255,255,255,.7); padding:14px 14px;
  cursor:pointer; display:grid; place-items:center; }
.renderbar-x svg { width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:2; }


/* ——— s23: trocas as the character card's payload + the 3-box troca page + proof popup ——— */
.trocalist { display:flex; flex-direction:column; gap:8px; }
.trocarow { display:flex; align-items:center; justify-content:space-between; gap:10px;
  background:var(--card); border:1px solid var(--line); border-radius:14px;
  padding:12px 13px; text-decoration:none; color:var(--ink); }
.trocarow:active { background:var(--paper-2); }
.trocarow-main { display:flex; flex-direction:column; gap:4px; min-width:0; }
.trocarow-main b { font-size:14.5px; }
.trocarow-scn { display:flex; align-items:center; flex-wrap:wrap; gap:4px;
  font-size:12px; color:var(--ink-soft); }
/* Claquete tiles (s23, option B): equal-width slate squares — self-contained units, so
   a many-scene troca WRAPS into a clean grid (the régua strip couldn't). 44px min tap. */
.cenachip { font:inherit; font-size:13px; font-weight:700; color:var(--ink);
  background:var(--paper-2); border:1px solid var(--line-2); border-radius:7px;
  min-width:44px; height:36px; display:inline-grid; place-items:center; padding:0 8px;
  cursor:pointer; font-variant-numeric:tabular-nums; letter-spacing:.03em; }
.cenachip:active { background:var(--accent); border-color:var(--accent); color:var(--on-accent); }
.trocarow-state { flex:none; font-size:12px; font-weight:600; color:var(--ink-faint); }
.trocarow-state.ok { color:var(--ok, #4c7a5a); }
.trocagap { display:block; margin-top:10px; font-size:13px; font-weight:600;
  color:var(--warn, #b0762e); text-decoration:none; }
.charcenas-list { display:flex; flex-direction:column; gap:2px; }
.charcenas-row { display:block; padding:9px 4px; font-size:13.5px; color:var(--ink);
  text-decoration:none; border-bottom:1px solid var(--line); }
.charcenas-row:last-child { border-bottom:none; }
/* troca page */
.trocacenas { font-size:13.5px; color:var(--ink-soft); margin-top:4px; }
.cenarow { display:flex; align-items:center; flex-wrap:wrap; gap:7px; margin-top:8px; }
.aviso-dismissable { display:flex; align-items:baseline; gap:8px; }
.aviso-dismissable form { margin-left:auto; }
.aviso-dismissable button { font:inherit; font-size:15px; color:var(--ink-faint);
  background:none; border:none; padding:0 4px; cursor:pointer; }
.bioproof { font:inherit; font-size:12px; font-weight:600; color:var(--accent);
  background:none; border:none; padding:0 2px; cursor:pointer; white-space:nowrap; }
/* The PRESCRIBED palette (s23b) — the character's color rule; swatch tap = remove */
/* THE FLUSH BAND (s24, her printed reference): equal blocks, zero gaps, hairline
   around the WHOLE band only (the cream-on-paper problem — a pale block with no
   outer rule optically vanishes). Fixed 44px height: cell aspect must NOT follow
   the count (square cells would make the band jump as colors are added). Matches
   the apresentação p1 bar — the card is a live preview of the print. */
.charpal { display:flex; align-items:stretch; gap:0; margin:14px 0 4px; height:44px;
  border:1px solid var(--line-2); border-radius:10px; overflow:hidden; }
.charpal form { display:contents; }
.charpal-sw { position:relative; flex:1 1 0; min-width:0; border:none; padding:0;
  cursor:pointer; display:block; }
.charpal-sw input[type=color] { position:absolute; inset:0; opacity:0; cursor:pointer; }
.charpal-sw.holding { filter:brightness(.72); }
.charpal-add { position:relative; flex:0 0 40px; display:grid; place-items:center;
  border:none; border-left:1px dashed var(--line-2); background:none;
  color:var(--ink-faint); font-size:18px; cursor:pointer; }
.charpal.empty { border-style:dashed; }
.charpal.empty .charpal-add { flex:1 1 auto; border-left:none; }
.charpal-add input[type=color] { position:absolute; inset:0; opacity:0; cursor:pointer; }
.charpal-hint { font-size:12.5px; color:var(--ink-faint); }
/* THE GLYPH TOOLBAR (Ficha A): four verbs as icons — they were four stacked lines
   of prose competing with the identity block. Equal cells, one-word captions; a tool
   with nothing to act on dims rather than vanishing (a toolbar that changes shape
   between visits is worse than one with a quiet key). */
.chartools { display:flex; gap:7px; margin:14px 0 4px; }
.chartool { flex:1; display:flex; flex-direction:column; align-items:center; gap:5px;
  padding:10px 4px 9px; border:1px solid var(--line); border-radius:11px;
  background:var(--card); color:var(--ink); text-decoration:none; cursor:pointer;
  font-family:inherit; }
.chartool svg { width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.chartool span { font-size:10px; letter-spacing:.03em; color:var(--ink-soft); }
.chartool:active { background:var(--paper-2); }
.chartool[disabled] { opacity:.4; }
.chartool.filled svg { color:var(--accent); }

/* Section head: the label keeps its quiet type, the ADD verb rides at the right edge
   (standalone action buttons died — the section owns its own +). */
/* the head carries the label's own rhythm (the .slabel margin moves up to it, so
   the flex row doesn't collapse the section spacing) */
.chsec { display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  margin:30px 2px 13px; }
.chsec .slabel { margin:0; }
.chsec-act { font-size:21px; line-height:1; color:var(--accent); text-decoration:none;
  padding:0 2px; }
/* The curation chips: extracted tones, tap to keep/drop (on = accent ring). */
.palcands { display:flex; flex-wrap:wrap; gap:7px; padding:4px 0 2px; min-height:38px; }
.palcand { width:34px; height:34px; border-radius:var(--r-ctl); border:1px solid var(--line-2);
  padding:0; cursor:pointer; opacity:.38; }
.palcand.on { opacity:1; outline:2.5px solid var(--accent); outline-offset:1.5px; }
.palsheet-hint { font-size:12px; color:var(--ink-faint); line-height:1.45; margin:2px 2px 8px; }

/* The Mesa montar-context mirror: the same flush band, in miniature. */
.montarctx-pal { display:inline-flex; gap:0; margin-left:7px; vertical-align:middle;
  border:1px solid rgba(255,255,255,.3); border-radius:3px; overflow:hidden; }
.montarctx-pal span { width:11px; height:13px; display:inline-block; }
.trocafix { margin-top:12px; }
.trocafix-row { display:flex; align-items:center; gap:8px; padding:8px 2px; flex-wrap:wrap; }
.trocafix-row label { font-size:12.5px; color:var(--ink-soft); flex:none; }
.trocafix-row select { flex:1; min-width:120px; font:inherit; font-size:13.5px; padding:8px 10px;
  border:1px solid var(--line-2); border-radius:10px; background:var(--paper-2); color:var(--ink); }
.trocafix-row button { font:inherit; font-size:13px; font-weight:700; padding:9px 14px;
  border-radius:10px; border:1px solid var(--accent); background:none; color:var(--accent); }
.opcol { display:flex; flex-direction:column; gap:16px; margin-top:16px; }
.opbox { background:var(--card); border:1px solid var(--line); border-radius:16px;
  padding:12px; }
.opbox.chosen { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset; }
.opimg { position:relative; display:block; border-radius:12px; overflow:hidden;
  background:var(--paper-2); aspect-ratio:3/4; }
.opimg img { width:100%; height:100%; object-fit:cover; display:block; }
.opimg svg { width:46%; height:auto; margin:18% auto; display:block; stroke:var(--line-2);
  fill:none; stroke-width:2; }
.opnum { position:absolute; top:8px; left:8px; font-size:11px; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--paper);
  background:rgba(31,26,32,.55); border-radius:7px; padding:3px 8px; }
.oppieces { display:flex; gap:6px; margin-top:9px; overflow-x:auto; }
.oppiece { flex:none; width:52px; height:52px; border-radius:var(--r-ctl); overflow:hidden;
  background:var(--paper-2); border:1px solid var(--line); }
.oppiece img { width:100%; height:100%; object-fit:cover; display:block; }
.opchoose { width:100%; margin-top:10px; font:inherit; font-size:14px; font-weight:700;
  padding:11px; border-radius:11px; border:1px solid var(--accent); background:none;
  color:var(--accent); cursor:pointer; }
.opchoose.chosen { background:var(--accent); color:var(--on-accent); }
.opinfo { margin-top:8px; font-size:13px; color:var(--ink-soft); }
.opnum-line { display:block; font-size:11px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-faint); text-decoration:none; margin-bottom:9px; }
.opprovar { display:block; margin-top:10px; text-align:center; font-size:13.5px;
  font-weight:700; color:var(--accent); text-decoration:none; padding:11px;
  border:1px dashed var(--line-2); border-radius:11px; }
.opchosen { margin-top:10px; text-align:center; font-size:14px; font-weight:700;
  color:var(--ok, #4c7a5a); padding:11px; }
.opempty { display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:6px; min-height:140px; border-style:dashed; text-decoration:none; }
.opempty-plus { font-size:28px; color:var(--accent); line-height:1; }
.opempty-lbl { font-size:13.5px; font-weight:600; color:var(--ink-soft); }
/* proof popup */
.proofpop { position:fixed; inset:0; z-index:96; }
.proofpop[hidden] { display:none; }
.proofpop-back { position:absolute; inset:0; background:rgba(20,16,10,.45); }
.proofpop-panel { position:absolute; left:14px; right:14px; top:50%; transform:translateY(-50%);
  max-width:480px; margin:0 auto; background:var(--paper); border-radius:16px;
  padding:14px 15px; max-height:70vh; display:flex; flex-direction:column;
  box-shadow:0 18px 50px rgba(0,0,0,.35); }
.proofpop-head { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.proofpop-head b { font-size:14.5px; }
.proofpop-x { border:none; background:none; font-size:18px; color:var(--ink-faint);
  cursor:pointer; padding:2px 6px; }
.proofpop-text { margin:10px 0 0; font-size:12.5px; line-height:1.55; white-space:pre-wrap;
  overflow-y:auto; font-family:inherit; color:var(--ink-soft); }

/* Recarga sheet (wallet-arc s32) — sibling of the fabsheet: bottom panel, backdrop tap
   closes. The Pix key is the hero (the app's job ends at copying it); steps read as a
   short numbered list, the WhatsApp conversation is the quiet fallback. */
/* NO DARK SCRIM — the headstone of the s41 cream-band hunt (7 rounds): iOS blinks the
   root canvas behind the top safe area when a full-screen composited layer changes, and
   NO open/close mechanism avoided it (animated, static, atomic, tree-persistent — all
   banded). The artifact is cream-on-DARK; remove the dark and it is invisible forever,
   by construction (TravelOps ratified the same route: kill the dark-overlay pattern).
   The sheet separates itself with DEPTH (the deep lifted shadow), not darkness; the
   transparent container still catches outside taps. Never re-add a dark full-screen
   layer behind the top safe area. */
.rcsheet { position:fixed; inset:0; z-index:210; display:flex; align-items:flex-end; }   /* the terminal out-of-credits door — ABOVE every other sheet (s59), incl. the polish .pash (96) and the Refazer .lightbox (200), which can summon it while open */
/* display:flex beats the [hidden] UA default — state it explicitly (the provarpanel
   footgun, s32: without this the sheet sits open on EVERY page, over the navbar). */
/* NEVER display:none (s41 round 6 — the real fix): the cream band is iOS exposing the
   root canvas at the top safe area while it ADDS or REMOVES the full-screen overlay's
   compositing layer. So the layer must NEVER enter or leave the tree — the closed sheet
   stays display:flex and only goes visibility:hidden + inert. Open/close then just
   toggle visibility (a paint, not a tree mutation) + the panel's .in rise. Round 5's
   regression was reverting this to display:none, which re-broke the (working) open.
   pointer-events:none keeps the invisible full-screen layer from eating taps. */
.rcsheet[hidden] { display:flex; visibility:hidden; pointer-events:none; }
.rcsheet-backdrop { position:absolute; inset:0; }   /* transparent click-catcher — the container paints the scrim */
.rcsheet-panel { position:relative; width:100%; max-width:520px; margin:0 auto; background:var(--paper);
  border-radius:20px 20px 0 0; overflow:hidden;
  /* Scrimless: DEPTH alone does the separating — a deep plum-charcoal lift; no
     hairline (it read as a stray white edge on device). */
  box-shadow:0 -12px 44px rgba(40,28,48,.38), 0 -2px 10px rgba(40,28,48,.16); }
/* The money seam opens WARM, not as a bill (s41): a plum --grad masthead carries the
   title + ONE reassurance line; the grad is dark in both themes, so the ink is fixed
   cream. Body padding moved to .rcsheet-bd so the mast bleeds full-width. */
.rcsheet-mast { background:var(--grad); padding:15px 18px 13px; }
.rcsheet-mast .rcsheet-head b { color:#FBF7F0; }
.rcsheet-mast .rcsheet-x { color:rgba(251,247,240,.55); }
.rcsheet-sub { margin:5px 0 0; font-size:12.5px; line-height:1.4; color:rgba(251,247,240,.75); }
.rcsheet-bd { padding:14px 18px calc(20px + env(safe-area-inset-bottom)); }
/* Never an ambush (s41): the backdrop fades and the panel rises — brief, the OS's
   learned sheet motion, not a teleport. TRANSITIONS driven by .in (acrvoSheetShow
   adds it a frame after un-hiding), never animations on the display flip — iOS
   paints the first composited frame of a fresh fixed overlay before an animation's
   from-state lands, flashing a misplaced cream strip at the top of the page. At
   opacity 0 that first frame paints nothing. */
.rcsheet .rcsheet-panel, .fbsheet .fbsheet-panel { opacity:0; transform:translateY(18px);
  transition:opacity .28s ease-out, transform .28s ease-out; }
.rcsheet.in .rcsheet-panel, .fbsheet.in .fbsheet-panel { opacity:1; transform:none; }
@media (prefers-reduced-motion: reduce) {
  .rcsheet .rcsheet-panel, .fbsheet .fbsheet-panel { transition:none; }
}
.rcsheet-head { display:flex; align-items:center; justify-content:space-between; }
.rcsheet-head b { font-size:17px; color:var(--ink); }
.rcsheet-x { border:none; background:none; font-size:24px; line-height:1; color:var(--ink-faint);
  cursor:pointer; padding:2px 6px; }
/* Steps = a plum number dot + a short label; the chips carry the payload. */
.rcsteps { display:flex; flex-direction:column; gap:13px; }
.rcstep { display:flex; gap:11px; align-items:flex-start; }
.rcstep-n { flex:none; width:22px; height:22px; border-radius:50%; background:var(--tint-2);
  color:var(--accent); font-size:12px; font-weight:700; display:grid; place-items:center; margin-top:1px; }
.rcstep-c { flex:1; min-width:0; font-size:14px; color:var(--ink); line-height:1.45; }
.rcstep-c > .rcsheet-key { margin-top:6px; }
/* The plan picker (rollout plan §2): fixed values, one selected, step 2 follows. */
.rcplans { display:grid; gap:8px; margin:0 0 14px; }
.rcplan { display:flex; align-items:center; justify-content:space-between; gap:10px;
  width:100%; padding:10px 14px; border-radius:var(--r-ctl); border:1px solid var(--line);
  background:var(--card); color:var(--ink); font:inherit; text-align:left; cursor:pointer; }
.rcplan.on { border-color:var(--accent); box-shadow:0 0 0 1.5px var(--accent) inset; }
.rcplan-l { display:flex; flex-direction:column; gap:1px; }
.rcplan-l b { font-size:14.5px; }
.rcplan-l small { font-size:11.5px; color:var(--accent); }
.rcplan-p { font-size:14.5px; font-weight:700; white-space:nowrap;
  font-variant-numeric:tabular-nums; }
.rcsheet-steps { margin:0; padding:0 0 0 20px; display:grid; gap:10px; font-size:14px; color:var(--ink); }
.rcsheet-key { display:flex; align-items:center; gap:8px; max-width:100%; margin-top:6px;
  padding:9px 12px; border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--paper-2, var(--paper));
  font-family:var(--sans); font-size:14px; color:var(--ink); cursor:pointer; }
.rcsheet-keytxt { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rcsheet-key svg { flex:none; width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.8; }
.rcsheet-copied { margin-left:8px; font-size:12px; color:var(--accent); font-weight:600; }
.rcsheet-wa { display:inline-block; margin-top:14px; font-size:13px; color:var(--accent);
  text-decoration:none; font-weight:600; }
.rcsheet-fallback { margin:8px 0 0; font-size:14px; color:var(--ink); }
.rcsheet-wa-main { font-size:15px; }
.rcsheet-pending { margin:2px 0 10px; padding:8px 12px; border-radius:10px;
  background:var(--paper-2); border:1px solid var(--line); font-size:13px; color:var(--ink-soft); }
.rcsheet-mail .rcsheet-keytxt { white-space:normal; word-break:break-all; text-align:left; }
.rcsheet-hint { display:block; margin-top:6px; font-size:12.5px; color:var(--ink-soft); }
/* LIVE PIX (s50): the QR is the sheet. */
.rcpix { display:flex; flex-direction:column; align-items:center; text-align:center; gap:10px; padding:4px 0 2px; }
.rcpix-qr { width:196px; height:196px; border-radius:12px; background:#fff; border:1px solid var(--line); display:grid; place-items:center; overflow:hidden; }
.rcpix-qr img { width:184px; height:184px; display:block; }
.rcpix-wait { font-size:12.5px; color:var(--ink-faint); padding:0 14px; line-height:1.4; }
.rcpix-copy { margin-top:0; }
.rcpix-line { margin:2px 0 0; font-size:14px; line-height:1.45; color:var(--ink); max-width:30ch; }
.rcpix-got { margin:4px 0 0; padding:9px 12px; border-radius:10px; background:var(--tint); color:var(--accent); font-weight:600; font-size:13.5px; }
.rcpix-got[hidden] { display:none; }
.rcsheet-support { display:inline-block; margin-top:16px; font-size:13px; color:var(--ink-soft);
  text-decoration:underline; }
.fbsheet { position:fixed; inset:0; z-index:87; display:flex; align-items:flex-end; }   /* scrimless — same rule as .rcsheet */
.fbsheet[hidden] { display:flex; visibility:hidden; pointer-events:none; }   /* tree-persistence, same as .rcsheet */
.fbsheet-backdrop { position:absolute; inset:0; }   /* transparent click-catcher */
.fbsheet-panel { position:relative; width:100%; max-width:520px; margin:0 auto;
  background:var(--paper); border-radius:18px 18px 0 0; padding:18px 18px calc(20px + env(safe-area-inset-bottom));
  box-shadow:0 -12px 44px rgba(40,28,48,.38), 0 -2px 10px rgba(40,28,48,.16); }
.fbsheet-head { display:flex; align-items:center; justify-content:space-between; }
.fbsheet-head b { font-size:17px; color:var(--ink); }
.fbsheet-x { border:none; background:none; font-size:24px; line-height:1; color:var(--ink-faint); padding:0 4px; }
.fbsheet-prompt { margin:8px 0 12px; font-size:14px; line-height:1.4; color:var(--ink-soft); }
.fbsheet-body textarea { width:100%; box-sizing:border-box; border:1px solid var(--line-2);
  border-radius:12px; background:var(--paper); color:var(--ink); font:inherit; font-size:15px;
  padding:12px; resize:vertical; min-height:110px; }
.fbsheet-send { width:100%; margin-top:12px; }
/* Optional screenshot (s41): a quiet dashed add-row; the real <input> overlays it
   transparently so iOS anchors the photo menu to the tap. Once chosen, the row hides
   and a thumbnail preview takes its place (one screenshot). */
.fbshot-add { position:relative; display:flex; margin-top:10px; cursor:pointer; }
.fbshot-add[hidden] { display:none; }   /* the class display:flex would else beat [hidden] */
.fbshot-add input { position:absolute; inset:0; opacity:0; width:100%; height:100%; cursor:pointer; }
.fbshot-add-face { flex:1; display:flex; align-items:center; gap:8px; justify-content:center;
  border:1px dashed var(--line-2); border-radius:var(--r-ctl); padding:11px 12px;
  font-size:13.5px; color:var(--ink-soft); }
.fbshot-add-face svg { width:19px; height:19px; fill:none; stroke:var(--ink-faint); stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; }
.fbshot-add-face small { color:var(--ink-faint); font-size:11.5px; }
.fbshot-previews { display:flex; gap:8px; margin-top:10px; }
.fbshot-previews[hidden] { display:none; }
.fbshot-preview { position:relative; margin-top:10px; width:96px; }
.fbshot-previews .fbshot-preview { margin-top:0; }
.fbshot-preview img { width:96px; height:96px; object-fit:cover; border-radius:var(--r-ctl);
  border:1px solid var(--line-2); display:block; }
.fbshot-x { position:absolute; top:-7px; right:-7px; width:24px; height:24px; border-radius:50%;
  border:none; background:var(--ink); color:var(--paper); font-size:15px; line-height:1; cursor:pointer;
  display:grid; place-items:center; box-shadow:0 1px 4px var(--shadow); }
.fbfieldwrap { position:relative; }
.fbfieldwrap textarea { display:block; }
.fbfieldwrap .fieldmic { position:absolute; right:8px; bottom:8px; width:38px; height:38px; padding:0;
  display:flex; align-items:center; justify-content:center; border-radius:50%;
  background:var(--paper); border:1px solid var(--line-2); box-shadow:0 1px 3px rgba(0,0,0,.10); }
.fbfieldwrap .fieldmic svg { width:19px; height:19px; }
.fbfieldwrap .fieldmic[data-state="rec"] { background:var(--red); border-color:var(--red); color:#fff; box-shadow:none; }
.fbsheet-done { padding:8px 2px 2px; }
.fbsheet-thanks { font-size:15px; line-height:1.4; color:var(--ink); margin:6px 0 16px; }
.fbsheet-close2 { width:100%; }

/* Seus convites (s35): the invite is a SEALED, sparkly envelope — collapsed until she opens
   it, so a scarce, occasional act doesn't hog the page on every visit. The ledger (sent /
   entered) stays OUTSIDE as status. All in the page language: card ground, one radius scale,
   tinted accents, static rose glints (motion-free — "the collection is calm"). */
.invsection { margin-top:24px; }
.invlabel { margin:0 0 12px 0; font-family:var(--sans); font-size:11px; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink-soft); }

.invenv { background:var(--card); border-radius:var(--r-card); border:1px solid var(--line-2); overflow:hidden; }
.invenv-cover { display:flex; align-items:center; gap:13px; padding:14px 16px; }
.invenv > summary { list-style:none; cursor:pointer; }
.invenv > summary::-webkit-details-marker { display:none; }
.invenv > summary::marker { content:""; }
.invenv-seal { position:relative; flex:none; width:42px; height:42px; border-radius:50%; background:var(--tint); display:grid; place-items:center; }
.invenv-mail { width:20px; height:20px; stroke:var(--accent); fill:none; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.invenv-mail rect { fill:var(--dot); }   /* pink-filled envelope (s58), mirrors the masthead's env--fill */
.invenv-glint { position:absolute; fill:var(--dot); }
.invenv-glint.g1 { width:11px; height:11px; top:-3px; right:-2px; }
.invenv-glint.g2 { width:7px; height:7px; bottom:-1px; left:-3px; opacity:.85; }
.invenv-glint.g3 { width:5px; height:5px; top:9px; right:-5px; opacity:.7; }
.invenv-txt { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.invenv-txt b { font-size:14.5px; font-weight:600; color:var(--ink); }
.invenv-txt small { font-size:11.5px; color:var(--ink-soft); }
.invenv-count { flex:none; font-size:12.5px; font-weight:700; color:var(--accent); background:var(--tint); border-radius:var(--r-pill); padding:3px 10px; }
.invenv-chev { flex:none; width:18px; height:18px; stroke:var(--ink-faint); fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; transition:transform .2s ease; }
.invenv[open] .invenv-chev { transform:rotate(90deg); }
.invenv[open] > summary { border-bottom:1px solid var(--hair); }
/* dormant slot: same footprint, greyed — a quiet WAITING state, never a dead button */
.invenv--off { background:var(--paper-2); border-color:var(--line); }
.invenv--off .invenv-seal { background:var(--line); }
.invenv--off .invenv-mail { stroke:var(--ink-faint); }
.invenv--off .invenv-txt b { color:var(--ink-soft); }
.invenv--off .invenv-txt small { color:var(--ink-faint); }

/* the form, now living INSIDE the opened envelope — its old bordered-card chrome stripped */
.invenv .invcard { border:none; background:none; box-shadow:none; border-radius:0; padding:12px 16px 14px; display:block; }
/* the [hidden] attr must beat that display:block — else Preparar's form never leaves and the
   share stage stacks BELOW it (the recurring author-display-defeats-hidden trap: install banner
   s31, .expupload s33, sig-modal Remover s35). This is WHY Preparar looked inert. */
.invenv .invcard[hidden] { display:none; }
.invcard-eyebrow { display:flex; align-items:center; gap:7px; font-family:var(--sans);
  font-size:10.5px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; color:var(--ink-soft); }
.invcard-eyebrow svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
/* the input stays 16px on purpose — anything smaller makes iOS zoom-jump on focus. Everything
   AROUND it shrinks so the field reads as the one focal element, not an oversized block. */
.invcard-line { display:flex; align-items:baseline; gap:9px; margin:11px 2px 2px; font-family:var(--sans); font-size:15px; color:var(--ink-soft); }
.invcard-line input { flex:1; min-width:0; border:none; border-bottom:1.5px dashed var(--line-2); border-radius:0; background:none;
  font-family:var(--sans); font-size:16px; color:var(--ink); padding:2px 2px 5px; outline:none; -webkit-appearance:none; appearance:none; }
.invcard-line input:focus { border-bottom-color:var(--accent); }
.invcard-line input::placeholder { color:var(--ink-faint); font-style:italic; }
/* The name field (s58): one standardized .phonewrap pill, no label — the cover + placeholder
   carry the meaning. The number hides behind a quiet door below it. */
.invcard-name { margin:2px 2px 0; }
/* The optional-number door (s58): a quiet disclosure, NOT a second prominent field. The door
   text names exactly when it's for you (only if the person isn't a saved contact); tapping it
   reveals the +55 auto-format field. Most invites skip it and use the contact picker. */
.invphone { margin:11px 2px 0; }
.invphone > summary { list-style:none; cursor:pointer; display:block; line-height:1.45;
  font-family:var(--sans); font-size:13px; color:var(--accent); padding:3px 0; -webkit-tap-highlight-color:transparent; }
.invphone-plus { margin-right:4px; }
.invphone > summary::-webkit-details-marker { display:none; }
.invphone > summary::marker { content:""; }
.invphone-plus { font-size:15px; line-height:1; font-weight:600; }
.invphone-door em { font-style:normal; color:var(--ink-faint); font-size:11.5px; }
.invphone[open] > summary { color:var(--ink-soft); margin-bottom:8px; }
/* +/− carried by CSS so it flips with the native details state (s59): + closed, − open —
   the − signals a second tap collapses the number field. */
.invphone-plus::before { content:"+"; }
.invphone[open] .invphone-plus::before { content:"\2212"; }
.invphone-field { margin:0 0 2px; }
.invcard-send { width:100%; margin-top:12px; padding:11px; font-size:13.5px; }
/* s65 (his call): the button carries the requirement — muted + reads "Diga pra quem é o
   convite" until a name is entered, then wakes to the active plum "Preparar o convite". */
.invcard-send.is-empty { background:var(--paper-2); border-color:var(--line-2); color:var(--ink-soft); }
.invcard-send.is-empty:active { background:var(--paper-2); }
.invcard-note { margin:9px 2px 0; font-family:var(--sans); font-size:11.5px; color:var(--ink-soft); line-height:1.4; }

/* the share stage — revealed in place of the form after Preparar (s35b). No token
   string on display: the two acts ARE the payload. */
.invshare { padding:14px 16px 15px; font-family:var(--sans); }
.invshare-head { display:flex; align-items:center; gap:9px; font-size:14px; color:var(--ink-soft); margin:0 0 13px; }
.invshare-head b { color:var(--ink); font-weight:600; }
.invshare-seal { flex:none; width:34px; height:34px; border-radius:50%; background:var(--tint); display:grid; place-items:center; }
.invshare-seal svg { width:17px; height:17px; stroke:var(--accent); fill:none; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.invshare-send { width:100%; padding:11px; font-size:13.5px; }
.invshare-quiet { display:flex; align-items:center; justify-content:center; gap:8px; margin-top:10px; color:var(--ink-faint); }
/* the quiet register — trocar / cancelar / any low-stakes text action beside a primary button */
.qlink { padding:5px 4px; background:none; border:none; font-family:var(--sans); font-size:12px;
  color:var(--ink-soft); cursor:pointer;
  text-decoration:underline dotted; text-underline-offset:3px; text-decoration-color:var(--line-2); }
/* THE SENT ROW (s50): a state, not an action — one row, a chevron, the verbs in the sheet. */
.invlist { background:var(--card); border-radius:var(--r-card); box-shadow:0 4px 14px var(--shadow); overflow:hidden; }
.invlist .invrow { background:none; border-radius:0; box-shadow:none; margin-top:0; }   /* one card, flat rows — not a card per row */
.invrow-tap { border:none; background:none; font:inherit; text-align:left; cursor:pointer; -webkit-appearance:none; appearance:none; -webkit-tap-highlight-color:transparent; padding:12px 16px; }
.invrow-tap + .invrow-tap { border-top:1px solid var(--hair); }
.invrow-tap:active { background:var(--paper-2); }
.invrow-ic.sent { background:var(--paper-2); color:var(--ink-soft); }
.invrow-chev { flex:none; width:18px; height:18px; stroke:var(--ink-faint); fill:none; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.invsheet-eye { padding:2px 12px 0; }
.invsheet-who { font-size:18px; font-weight:800; letter-spacing:-.01em; padding:4px 12px 0; }
.invsheet-when { font-size:13.5px; color:var(--ink-soft); padding:2px 12px 10px; }
.invsheet-act { width:100%; }

/* the ENTERED count: the smallest, quietest line on the page — a tappable disclosure */
.inventered { margin-top:11px; }
.inventered-sum { list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:5px;
  font-size:13px; color:var(--ink-faint); text-decoration:underline dotted; text-underline-offset:3px; }
.inventered-sum::-webkit-details-marker { display:none; }
.inventered-sum::marker { content:""; }
.inventered-list { margin-top:2px; }
.invrow { display:flex; align-items:center; gap:12px; width:100%; box-sizing:border-box;
  padding:12px 14px; border:none; background:var(--card); border-radius:var(--r-ctl);
  box-shadow:0 2px 8px var(--shadow); margin-top:9px; font-family:var(--sans); text-align:left; }
.invrow-ic { flex:none; width:40px; height:40px; border-radius:50%; display:grid; place-items:center; background:var(--tint); color:var(--accent); }
.invrow-ic.ok { color:var(--on-accent); background:var(--accent); }
.invrow-ic svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.invrow-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.invrow-body b { font-size:14.5px; font-weight:600; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.invrow-body small { font-size:12px; color:var(--ink-soft); }
.invrow-act { flex:none; border:1.5px solid var(--accent); border-radius:var(--r-pill); background:transparent;
  color:var(--accent); font-family:var(--sans); font-size:13px; font-weight:600; padding:7px 15px; cursor:pointer; -webkit-appearance:none; appearance:none; }
.invarrive { text-decoration:none; color:var(--ink); }

/* Pieces-as-manifest on the look page (s32 S/N pass): the page leads with the WORK
   (renders + generator), so the pieces are the compact supporting cast below — small
   tiles, the whole look at a glance, not the ~590px browse grid it inherited from the
   Acervo. Scoped to the look page; the Acervo keeps its big browse tiles. Long-press
   remove + the add-drawer are untouched (same .bcard/.tile the JS builds). */
.lookmanifest { display:grid; grid-template-columns:repeat(auto-fill, minmax(78px, 1fr));
  gap:12px 10px; margin-bottom:10px; }
.lookmanifest .tile { gap:5px; }
.lookmanifest .tile .img { border-radius:5px; }
.lookmanifest .tile .nm { font-size:11.5px; line-height:1.2; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.lookmanifest .tile .sb { display:none; }        /* category is noise in a manifest */
.lookmanifest .hold-ring svg { width:30px; height:30px; }

/* Look page blocks (s35b): the pieces + the generator each live in a lifted house-
   style card (rede/Mesa shading), and the rose-tick eyebrow sits ABOVE the card
   (canon) — not inside it. The pieces are a fixed 3-up grid of photo-first tiles;
   drag-reorder like the piece-photo strip — press a tile, drag to reposition; tap
   opens, long-press removes. The order persists as look_item.sort_order. */
.lookblock { background:var(--card); border-radius:var(--r-card); box-shadow:0 6px 22px var(--shadow);
  padding:13px 15px 15px; margin:0; }
.lookrow { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:14px 10px; margin:0; align-items:start; }
/* s75 — reorder is a 2D drag (the 3-col grid wraps), which needs touch-action:none so an
   upward drag reaches slot 1 (pan-y lets iOS steal it as a scroll). But tiles owning every
   gesture ate the page scroll — a swipe on a tile went nowhere. So reorder now lives behind a
   section toggle: DEFAULT = pan-y (scroll from anywhere, the daily need); only WHILE .reordering
   do the tiles own the 2D drag. */
.lookrow .bcard { touch-action:pan-y; }
.lookrow.reordering .bcard { touch-action:none; cursor:grab; }
/* s77 (Option B, his call): the image carries no border of its own — the card frame (below)
   provides the hairline, mirroring the NA MESA picker's .orcpickcell. */
.lookrow .tile .img { border:none; }
/* Option C (s75, his call): while reordering, a faint plum WASH behind the whole grid + a gentle
   lift on each tile + a cue line (::after, so it stays last through add/remove). No border line
   at all — softer than the framed A. The wash lives only in the mode; a resting grid is unchanged. */
.lookrow.reordering { border-radius:12px; padding:11px; background:color-mix(in srgb, var(--accent) 8%, transparent); }
.lookrow.reordering .tile { box-shadow:0 4px 12px color-mix(in srgb, var(--accent) 26%, transparent); }
.lookrow.reordering::after { content:"arraste pra trocar a ordem"; grid-column:1 / -1; text-align:center;
  font-size:11px; line-height:1.3; color:var(--accent); margin-top:2px; }
/* the lock-glyph trigger by the Peças eyebrow: a FILLED padlock — plum-on-white at rest (travado,
   page scrolls), white-on-plum with an OPEN shackle while reordering. The keyhole is a real gap
   filled with the disc colour, so it reads as a punched hole. Mirrors the rede eye's off/on. */
/* Just the padlock — NO disc (his call): always plum, and the ONLY state cue is the shackle,
   closed (travado, page scrolls) vs open (reordering). Absolute so it rides the eyebrow's far
   right without growing the line; even 18px glyph so the raster origin lands on a whole pixel. */
.lookreorder-toggle { position:absolute; right:2px; top:50%; transform:translateY(-50%); flex:none;
  width:28px; height:28px; padding:0; border:none; background:none; color:var(--accent); cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; -webkit-tap-highlight-color:transparent; }
.lookreorder-toggle svg { width:18px; height:18px; }
.lookreorder-toggle .lk-hole { fill:var(--paper); stroke:none; }   /* a gap the page shows through */
.lookreorder-toggle .lk-open { display:none; }
.lookreorder-toggle.on .lk-closed { display:none; }
.lookreorder-toggle.on .lk-open { display:block; }
.lookreorder-toggle[hidden] { display:none; }
/* s77 (Option B, his call): each piece is a bordered cream card inside the Peças panel —
   image clipped by the card, size in a CENTERED cream tab. Sizeless → no .sb → no tab (align-
   items:start on the grid keeps the sizeless card from stretching into a captioned neighbour). */
.lookrow .tile { gap:0; background:var(--paper); border:1px solid var(--line); border-radius:12px; overflow:hidden; }
.lookrow .tile .img { border-radius:0; }
.lookrow .tile .sb { font-size:10.5px; color:var(--ink-faint); margin-top:0; padding:6px 6px 7px; text-align:center; line-height:1.25;
  text-transform:none; letter-spacing:.01em;   /* a quiet caption, not a shouty uppercase label */
  overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
/* The STACKED caption (s44) opts OUT of the 2-line clamp above — each datum (size · owner ·
   status) is its own line, so a sized rede piece keeps its status line instead of clamping
   it off. Each line ellipsizes on its own. */
.lookrow .tile .sb.sbstack { display:flex; flex-direction:column; align-items:center; overflow:visible;
  -webkit-line-clamp:none; }
.lookrow .hold-ring svg { width:30px; height:30px; }
.lookrow .bcard.dragging .tile { transform:scale(1.06); transition:none; }
.lookrow .bcard.dragging .tile { box-shadow:0 0 0 2px var(--accent), 0 10px 20px var(--shadow-strong); }
/* The drop-slot the shared reorder module (app.js, s36) leaves where the lifted tile
   was — a grid item like the others (1fr), height set inline to the tile's, so the row
   keeps its shape and the gap tracks the drag. Generic, reused by the vitrine tray. */
.reorder-ph { border-radius:var(--r-ctl); background:var(--tint); border:1.5px dashed var(--line-2); box-sizing:border-box; }
/* Tighter header (s35b, S/N): pull the title up toward the topbar and let the seam
   underline it, so the name doesn't float in dead space. Scoped to the look page. */
.look-detail .tt { margin-top:12px; }
/* One render is the payload, not a grid cell (s35b, S/N): a lone prova fills the block
   width instead of sitting in half a 2-col grid beside dead space. 2+ keep the grid. */
.grid.onerender { grid-template-columns:1fr; }
/* HERO + THUMB STRIP for look provas (s59): the cover prova is a BIG inspectable hero (reuses
   .bcard/.tile/.img, so a 2:3 full-width image), the others a thumb switcher below. Tap a thumb
   → it becomes hero + cover. The cover marker lives on the thumb (ring + star), never on the hero. */
.provahero { display:block; margin:0; }
.provahero .provahero-card { width:100%; position:relative; }
/* s74 — reframe in place on the look hero: clip the zoom, kill page-scroll while adjusting,
   and float the Confirmar/Cancelar bar in flow below the hero (not the absolute hero overlay). */
.provahero .provahero-card .img { overflow:hidden; }
.provahero .provahero-card .img.reframing { touch-action:none; cursor:grab; }
/* s75 — reframe controls live ON the hero, lower-right. A permanent white "adjust" glyph
   (diagonal move arrows, black) flips to a dark check (save + close) while adjusting, and a
   dark revert glyph (back to the render's original framing) appears beside it. This kills the
   below-hero bar so nothing lands under the nav, and keeps save reachable without scrolling. */
.reframectrls { position:absolute; right:8px; bottom:8px; z-index:6; display:flex; gap:8px; }
.reframebtn { width:38px; height:38px; padding:0; border:none; border-radius:9px; cursor:pointer;
  display:flex; align-items:center; justify-content:center; -webkit-tap-highlight-color:transparent; }
.tile .img .reframebtn svg { width:20px; height:20px; opacity:1; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.reframe-toggle { background:var(--paper); box-shadow:0 0 0 .5px rgba(0,0,0,.14); }
.tile .img .reframe-toggle svg { stroke:#1a1a1a; }
.reframe-toggle:disabled { opacity:.6; cursor:default; }
.reframe-toggle .rf-check { display:none; }
.reframe-revert { background:rgba(40,28,48,.62); display:none; }
.tile .img .reframe-revert svg { stroke:#fff; }
.provahero-card.reframing .reframe-toggle { background:rgba(40,28,48,.62); box-shadow:none; }
.provahero-card.reframing .reframe-toggle svg { stroke:#fff !important; }
.provahero-card.reframing .reframe-toggle .rf-move { display:none; }
.provahero-card.reframing .reframe-toggle .rf-check { display:block; stroke-width:2.4; }
.provahero-card.reframing .reframe-revert { display:flex; }
.provahero-card.reframing .tileshare { display:none; }
/* s75 — the look hero's Enviar disc matches the reframe glyph's size (his call), so the two
   corner controls read as a pair on the prova. */
#provaHeroShare { width:38px; height:38px; }
#provaHeroShare svg { width:19px; height:19px; }
/* s75 — the Excluir look button lost its divider hairline (his call); a plain gap keeps it apart. */
.lookdel-form { margin-top:22px; }
/* s62 — the Arrumar button sits equidistant from the render above and the thumb strip below
   (was 8px above / 14px below), and a touch taller for presence. */
.provahero-acts { display:flex; margin-top:14px; }
.provahero-acts .renderact { flex:1; padding-top:10px; padding-bottom:10px; }
/* s75 (his call): the Provar de novo door matches the Ajustar prova door — same outlined,
   non-consequential style + taller padding (doors open a dropdown; they don't spend a credit). */
.provargen .renderact { padding-top:10px; padding-bottom:10px; }
/* s75 — a tap blocked at the prova cap SHAKES the button (option B) so it never reads as dead. */
@keyframes acrvo-shake { 0%,100%{transform:translateX(0)} 18%{transform:translateX(-5px)} 38%{transform:translateX(5px)} 58%{transform:translateX(-3px)} 78%{transform:translateX(3px)} }
.shake-no { animation:acrvo-shake .42s ease; }
.provaback { display:flex; align-items:flex-start; gap:8px; margin:9px 2px 0; font-size:12.5px;
  line-height:1.4; color:var(--ink-soft); background:none; border:none; padding:0; text-align:left; width:100%; }
.provaback[hidden] { display:none; }   /* author display:flex beats the UA [hidden] — restore it */
.provaback svg { flex:none; width:17px; height:17px; margin-top:1px; stroke:var(--ink-faint); fill:none;
  stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.provaback-go { background:none; border:none; padding:0; font:inherit; color:var(--accent); font-weight:600;
  cursor:pointer; -webkit-tap-highlight-color:transparent; }
/* 4 across (s59): a grid that fills the content width so the thumbs sit equidistant, exactly
   under the Arrumar button, a bit bigger than a fixed strip. Base caps at 4 (one row), Studio
   at 8 (wraps to two rows of 4) — the cap is enforced on generation, not here. */
.provastrip { display:grid; grid-template-columns:repeat(4, 1fr); gap:8px; margin-top:14px; }
.provathumb { aspect-ratio:2/3; border-radius:2px; overflow:hidden; padding:0;
  border:1px solid var(--line); background:var(--paper-2); cursor:pointer; position:relative;
  -webkit-tap-highlight-color:transparent; }   /* 2px = the hero img's radius (.tile .img), so they match */
.provathumb img { width:100%; height:100%; object-fit:cover; display:block; }
.provathumb-star { display:none; }
.provathumb.on .provathumb-star { display:grid; place-items:center; position:absolute; top:3px; right:3px;
  width:17px; height:17px; border-radius:50%; background:var(--paper); box-shadow:0 1px 3px rgba(20,16,10,.25); }
.provathumb-star svg { width:11px; height:11px; fill:var(--accent); stroke:none; }
/* s49 (his call): the look page shows the SHARED Em quem? instrument exactly as the Mesa
   does — the 104px face, the "veste o look" label. The s35b shrink-to-34px override went:
   the panel now opens under "Gerar outra imagem" with the prova scrolled away, so the
   "redundant face" it was fixing is no longer on screen, and the tiny face read as a bug. */
/* The generating beat (s44): while a prova renders (single-shot page POST), the composer
   collapses to this — the composer is inert until the reload, so the wait shows only WHO
   + the seconds reassurance, with the spinner as the pre-attentive "it's working". */
.lookgen-wait { display:flex; flex-direction:column; align-items:center; gap:3px; text-align:center;
  padding:24px 12px 20px; color:var(--ink); }
/* display:flex above would beat the UA [hidden] rule — so a `hidden` beat would never
   hide (s59 bug: the Mesa's toggled 'Gerando a prova…' stayed visible forever). Honor it. */
.lookgen-wait[hidden] { display:none; }
.lookgen-wait .btnspin { width:20px; height:20px; margin:0 0 7px; }
.lookgen-wait b { font-size:15px; font-weight:600; }
.lookgen-wait small { font-size:12.5px; color:var(--ink-faint); }
/* Footers inside a look block — the add-pieces drawer and the generator each ride
   a hairline under the content above, reading as the card's own action. */
.lookblock .lookaddfoot { margin:14px 0 0; padding-top:13px; border-top:1px solid var(--hair); }
.lookgen { margin-top:14px; }   /* s75 (his call): divider hairline below the thumbs removed */
.lookblock > .lookgen:first-child { margin-top:0; padding-top:0; border-top:none; }

/* Gallery door (s32, Android-only OS reconcile): a quiet text+icon row under the two
   camera glyphs — a way to import existing photos where the OS gives no camera-or-
   library menu. Hidden by default; app.js reveals it on Android only. */
.fabgallery { display:flex; align-items:center; justify-content:center; gap:8px;
  margin:2px auto 4px; padding:9px 14px; border:1px solid var(--line-2); border-radius:11px;
  background:var(--paper); color:var(--ink-soft); font-family:var(--sans); font-size:13px;
  font-weight:500; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.fabgallery svg { width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.fabgallery input { display:none; }
.fabgallery:active { background:var(--paper-2); }
/* OS-adaptive doors (s33): the Android camera/gallery doors are hidden by default and
   shown ONLY on Android, gated on the html.os-android class stamped at load (base.html
   head). This replaces ship-hidden + a JS reveal that a stray author `display` kept
   defeating (the doors leaked onto iOS three times). Convention for any future door:
   `#id { display:none }` + `html.os-android #id { display:<its natural display> }`. */
#fabGalleryDoor, #pieceGalleryTile, #provarCameraLabel,
#rentExpGal, #sigGal, #projExpGal, #sigGalP, #charPhotoGal { display:none; }
html.os-android #fabGalleryDoor { display:flex; }
html.os-android #pieceGalleryTile { display:grid; }
html.os-android #provarCameraLabel { display:flex; }
html.os-android #rentExpGal, html.os-android #sigGal,
html.os-android #projExpGal, html.os-android #sigGalP { display:inline-flex; }
html.os-android #charPhotoGal { display:flex; }

/* Coach hint pill (s32): a bottom-centered teach pill above the nav — the app's proven
   idiom (the FAB voice tip), robust and calm, distinct from the top alert banners. Tap
   anywhere to dismiss. Never a top banner. */
/* .coachhint retired (s49): no floating hint pills anywhere */
@keyframes coachpop { from { opacity:0; transform:translate(-50%, 6px); } to { opacity:1; transform:translate(-50%, 0); } }

/* Ajustes toggle row (s32) — a checkbox styled as a switch, matching the calm setrow. */
.setrow-toggle { display:flex; align-items:center; gap:12px; cursor:pointer; }
.setrow-toggle > span:first-child { flex:1; min-width:0; }
.setrow-toggle input { position:absolute; opacity:0; width:0; height:0; pointer-events:none; }
.setrow-toggle .switch { flex:none; width:48px; height:28px; border-radius:16px; background:var(--line-2);
  position:relative; transition:background .18s; }
.setrow-toggle .switch::after { content:""; position:absolute; top:3px; left:3px; width:22px; height:22px;
  border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.25); transition:transform .18s; }
.setrow-toggle input:checked ~ .switch { background:var(--accent); }
.setrow-toggle input:checked ~ .switch::after { transform:translateX(20px); }

/* ── Remote signing (s38, Q2) ─────────────────────────────────────────────── */
.sigsend { display:block; width:100%; text-align:center; margin:4px 0 8px; }
.siglink { display:flex; align-items:center; gap:8px; width:100%; margin:0 0 12px;
  padding:9px 12px; border-radius:var(--r-ctl); border:1px dashed var(--line-2);
  background:none; color:var(--ink-soft); font:inherit; font-size:12px; cursor:pointer; }
.siglink-url { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; text-align:left; }
.siglink svg { width:15px; height:15px; stroke:currentColor; stroke-width:1.6;
  fill:none; flex:none; }
.siglink-ok { color:var(--ok); font-weight:600; white-space:nowrap; }
/* the client's signature pad (public /assinar page) */
.signpad-wrap { position:relative; }
.signpad { display:block; width:100%; aspect-ratio:5/2; border-radius:var(--r-ctl);
  border:1.5px dashed var(--line-2); background:var(--card); touch-action:none; }
.signpad-clear { position:absolute; top:8px; right:8px; border:none; background:none;
  color:var(--ink-faint); font:inherit; font-size:12px; text-decoration:underline;
  cursor:pointer; }

/* ── The pedido handshake (idiom 23) ─────────────────────────────────────────
   The rede request's human surfaces: the borrower's note (a quoted quiet line on
   the card and on both rental pages) and the pedir form's optional message box —
   same white-field token every real input wears. */
.pedirnote { display:block; width:100%; margin-top:12px; border:1px solid var(--line-2);
  border-radius:var(--r-ctl); padding:11px 13px; font-family:var(--sans); font-size:16px;
  color:var(--ink); background:var(--field); outline:none; resize:none; line-height:1.4; }
.pedirnote:focus { border-color:var(--line-1); }
.pedirnote::placeholder { color:var(--ink-faint); }
.pedidonote { font-size:14px; color:var(--ink-soft); line-height:1.5; font-style:italic;
  margin:10px 2px 0; }
.cardnote { font-size:13px; color:var(--ink-soft); font-style:italic; line-height:1.45;
  margin-top:6px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; }

/* ── The look as manifest (s40; s40b: ripened status disclosure) ──────────────
   A <details> under the look's Peças. The SUMMARY is the always-on origin glance
   (idiom 14 — the count keeps the closed state honest); the PANEL holds the
   sourcing controls, disclosed on tap and default-open only while there's still
   something to pedir (idiom 6). Muted by design (idiom 5) — logistics under the
   creative surface, never a banner — but the send is the panel's clear primary. */
.lookprov { margin:12px 2px 2px; padding-top:10px; border-top:1px solid var(--line-2); }
/* s60 — Origem/Adicionar are their own cards now, not in-card rows: drop the separator the
   in-card version drew, and let the .lookblock padding own the spacing. Base Origem IS a card
   (.lookblock.lookprov); Estúdio's <details.lookprov> sits INSIDE a card (child selector). */
.lookblock.lookprov { margin:0; padding-top:13px; border-top:none; }
/* s60 — the base Origem card owns its top padding; the panel shouldn't add a second one, and
   the first row shouldn't carry its inter-row top margin (that stacked ~25px above the owner
   row when there are no dates). */
.lookblock.lookprov > .lprov-panel { padding-top:0; }
.lookblock.lookprov > .lprov-panel > :first-child { margin-top:0; }
.lookblock > .lookprov { margin:0; padding-top:0; border-top:none; }
/* the always-on glance riding the Origem eyebrow keeps its own casing (not the eyebrow's caps) */
.mesasec-glance { text-transform:none; }
/* the Adicionar picker header reuses the Origem summary row → one disclosure marker app-wide */
.lookadd[open] .lprov-chev { transform:rotate(90deg); }
.lprov-sum { display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
  padding:2px 0; }
.lprov-sum::-webkit-details-marker { display:none; }
.lprov-sumtext { flex:1; font-size:13px; color:var(--ink-soft); }
/* s62 — the Adicionar summary mirrors an Origem source row: the tint-disc glyph + the scope
   line, no in-card title (the eyebrow carries 'Adicionar peça'). Scoped to .lookadd-sum. */
.lookadd-sum { align-items:center; }
.lookadd-scopes { flex:1; min-width:0; font-size:13.5px; color:var(--ink-soft); }
.lprov-chev { width:16px; height:16px; stroke:var(--ink-faint); stroke-width:2;
  fill:none; stroke-linecap:round; stroke-linejoin:round; transition:transform .15s ease;
  flex:none; }
.lookprov[open] .lprov-chev { transform:rotate(90deg); }
.lprov-panel { padding-top:10px; }
/* The manifest's dates REUSE the shared .pedirwhen/.datefld idiom (s40c fix): it
   carries the s27 iOS date-input fix, so don't restyle the input here. */
.lprov-panel .pedirwhen { margin:2px 0 12px; }
input.lprov-miss { border-color:var(--warn); }
.lprov-note { margin-top:8px; font-size:14px; padding:8px 11px; }
.lprov-row { display:flex; align-items:center; gap:10px; margin-top:12px; min-height:34px; }
.lprov-owner { display:flex; align-items:center; gap:6px; font-size:13.5px;
  color:var(--ink-soft); min-width:0; flex:1; }
.lprov-owner svg { width:14px; height:14px; stroke:var(--accent); stroke-width:1.6;
  fill:none; flex:none; }
.lprov-owner b { font-weight:600; color:var(--ink-faint); }
.lprov-st { font-size:13px; color:var(--ink-soft); text-decoration:none; flex:none; }
.lprov-st.ok { color:var(--ok); }
.lprov-send { border:none; border-radius:var(--r-ctl); background:var(--accent);
  color:var(--on-accent); font-family:var(--sans); font-size:13.5px; font-weight:600;
  padding:9px 18px; cursor:pointer; flex:none; -webkit-appearance:none; appearance:none; }
.lprov-send:active { background:var(--accent-press); }
.lprov-send:disabled { opacity:.6; }
/* The base composer (s48, the WhatsApp manifest): the send is a green ask, the
   dates ride the panel once, the owner row reuses the manifest's own bones. */
.lprov-wago { background:var(--wa); text-decoration:none; display:inline-block; }
.lprov-wago:active { background:#25613E; }
/* B (s62, his call): a sent acervo's ask recedes to a ghost/outline — the still-to-send SOLID
   buttons pop out of a stack so you scan by weight, not by reading each label. The border
   replaces 1.5px of padding so it keeps the solid's box size; --ok (a lighter green in dark
   mode) keeps the label legible on the card in both themes. Order stays the origin order. */
.lprov-wago.lprov-wago--sent { background:transparent; border:1.5px solid var(--ok);
  color:var(--ok); padding:7.5px 16.5px; }
.lprov-wago.lprov-wago--sent:active { background:color-mix(in srgb, var(--ok) 12%, transparent); }
.lprov-who { display:flex; align-items:center; gap:6px; font-size:13.5px;
  color:var(--ink-soft); min-width:0; flex:1; }
.lprov-dates { margin-top:10px; }
/* s60 — the owner-identity row (Option 1): rede glyph in a tint disc, name first, count on a
   subline. Turns the card's dead space into a source's face. */
.lprov-src { display:flex; align-items:center; gap:12px; min-height:38px; }
/* Many sources → a clean divided list, capped at 3 with the rest behind an expander (so a
   heavily cross-sourced look never walls the page). One source = one flush row (13/15 card). */
.lprov-srclist { display:flex; flex-direction:column; margin-top:12px; }
.lprov-srclist > .lprov-src { padding:12px 0; }
.lprov-srclist > .lprov-src + .lprov-src { border-top:1px solid var(--line); }
.lprov-srclist > :first-child { padding-top:0; }
.lprov-srclist > .lprov-src:last-child { padding-bottom:0; }
.lprov-more { border-top:1px solid var(--line); }
.lprov-more > summary { padding:12px 0; }
.lprov-more[open] .lprov-chev { transform:rotate(90deg); }
.lprov-more .lprov-src { padding:12px 0; }
.lprov-more .lprov-src + .lprov-src { border-top:1px solid var(--line); }
.lprov-more .lprov-src:last-child { padding-bottom:0; }
/* s61 — the base Origem DROPDOWN: the summary rests on the source rows (read-only), the body
   holds the dates/nota form + the Pedir actions, revealed on tap. */
.lprov-drop { }
.lprov-dropsum { display:flex; align-items:flex-start; gap:10px; cursor:pointer; list-style:none;
  -webkit-tap-highlight-color:transparent; }   /* chevron stays at the TOP as the source list grows (s62) */
.lprov-dropsum::-webkit-details-marker { display:none; }
.lprov-dropsum > .lprov-srclist { flex:1; min-width:0; margin-top:0; }
.lprov-dropchev { width:16px; height:16px; stroke:var(--ink-faint); stroke-width:2; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:none; transition:transform .15s ease; }
.lprov-drop[open] .lprov-dropchev { transform:rotate(90deg); }
.lprov-moreflat { display:block; font-size:12.5px; color:var(--ink-faint); padding:11px 0 0;
  margin-top:11px; border-top:1px solid var(--line); }
.lprov-drop[open] > .lprov-panel { border-top:1px solid var(--line); margin-top:13px; padding-top:13px; }
.lprov-acts { display:flex; flex-direction:column; gap:8px; margin-top:12px; }
.lprov-acts .lprov-send { width:100%; }
.lprov-acts:first-child { margin-top:0; }   /* no dates above (nothing to pedir-new) → flush */
.lookprov.confirming .lprov-drop { display:none; }   /* the composer takeover replaces the dropdown */
.lprov-srcglyph { flex:none; width:38px; height:38px; border-radius:11px; background:var(--tint);
  display:flex; align-items:center; justify-content:center; }
.lprov-srcglyph svg { width:21px; height:21px; fill:none; stroke:var(--accent); stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; }
.lprov-srcmeta { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.lprov-srcname { font-size:15px; font-weight:600; color:var(--ink); }
.lprov-srcsub { font-size:12.5px; color:var(--ink-faint); }
.lprov-srcsub .ok { color:var(--ok); }
/* the how-it-works, moved UNDER the card (s60) — a quiet footnote, not floating inside */
/* s62 — folded INTO the Origem card, under the source rows: a hairline divides it from them. */
.lookprov-foot { display:flex; align-items:flex-start; gap:6px; margin:13px 0 0; padding-top:13px;
  border-top:1px solid var(--line); font-size:12px; color:var(--ink-faint); line-height:1.45; }
.lookprov-foot svg { flex:none; width:14px; height:14px; margin-top:1px; fill:none;
  stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
#lookSourceWrap.ticket-lit .lookprov-foot { display:none; }   /* recede during the spotlight */
/* s44: the pre-send confirm strip (names owner · count · dates) and the in-place done row. */
.lprov-owner[hidden] { display:none; }   /* explicit display:flex above beats the UA [hidden] rule */
/* The takeover confirm card (s44): while it's up the disclosure's inputs + owner rows
   recede, so the card sits right under the pieces. It's a SUMMARY, not a form — owner,
   terms once (no repeated date), one optional per-acervo message, then the actions. */
.lookprov.confirming > .lprov-sum,
.lookprov.confirming .pedirwhen,
.lookprov.confirming .pedirjob,
.lookprov.confirming .pedirnote,
.lookprov.confirming .lprov-row,
.lookprov.confirming .lprov-srclist,
.lookprov.confirming .lprov-dates,
.lookprov.confirming .payerfld,
.lookprov.confirming .payerother,
.lookprov.confirming .sighint { display:none; }
/* s49: on base the takeover keeps the card flush under the amber grid */
.lookprov.confirming .lticket { margin-top:0; }
.lprov-confirm { background:var(--card); border:1.5px solid var(--accent); border-radius:14px; padding:14px; }
.lprov-confirm-h { font-size:15px; font-weight:600; color:var(--ink); }
.lprov-confirm-h b { font-weight:600; }
.lprov-confirm-terms { font-size:12.5px; color:var(--ink-soft); margin-top:2px; }
.lprov-msg { width:100%; box-sizing:border-box; margin-top:11px; padding:9px 12px; border:1px solid var(--line-2);
  border-radius:10px; background:var(--paper); font-family:var(--sans); font-size:13.5px; color:var(--ink);
  -webkit-appearance:none; appearance:none; }
.lprov-msg:focus { outline:none; border-color:var(--accent); }
.lprov-confirm-acts { display:flex; align-items:center; gap:14px; margin-top:12px; }
.lprov-go { border:none; border-radius:var(--r-ctl); background:var(--accent); color:var(--on-accent);
  font-family:var(--sans); font-size:13.5px; font-weight:600; padding:9px 18px; cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.lprov-go:disabled { opacity:.6; }
.lprov-cancel { border:none; background:none; color:var(--ink-soft); font-family:var(--sans);
  font-size:13.5px; padding:9px 4px; cursor:pointer; }
.lprov-st--fresh { color:var(--accent); font-weight:500; }
.lprov-row.just-sent { border-radius:8px; animation:lprovJustSent 2.6s ease forwards; }
@keyframes lprovJustSent {
  0%,65% { background:color-mix(in srgb, var(--accent) 12%, transparent); }
  100%   { background:transparent; }
}
.pedirjob { display:block; width:100%; margin-top:12px; border:1px solid var(--line-2);
  border-radius:var(--r-ctl); padding:11px 13px; font-family:var(--sans); font-size:16px;
  color:var(--ink); background:var(--field); outline:none; -webkit-appearance:none;
  appearance:none; }

/* ── Current-job context + billing (s40c) ────────────────────────────────────
   The Rede chip that names the trabalho she's sourcing for (quick pedidos default
   to it — visible, never a silent mode); the job-page "trabalhar neste job" toggle;
   and the faturar-para lines that name who a pedido invoices. */
.jobctx { display:flex; align-items:center; gap:8px; margin:16px 0; padding:9px 12px;
  border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--card); }
.jobctx.on { border-color:var(--accent); background:var(--tint); }
.jobctx-lead { font-size:12.5px; color:var(--ink-faint); flex:none; }
.jobctx-sel { flex:1; min-width:0; border:none; background:none; outline:none;
  font-family:var(--sans); font-size:14px; color:var(--ink); -webkit-appearance:none;
  appearance:none; }
/* .jobwork retired (s43c) — the current-job toggle is now the .jsec-atual corner pill. */
.jobfiscal > summary { font-size:13px; }
/* Breathing room under the disclosure title so the first field's label ("Razão
   social") doesn't butt against "Dados para nota fiscal". */
.jobfiscal > .form { margin-top:14px; }
.billto { font-size:13px; color:var(--ink-soft); margin:8px 2px 0; }
.billto span { text-transform:uppercase; font-size:11px; letter-spacing:.04em;
  color:var(--ink-faint); margin-right:6px; }

/* The job's fiscal fields reuse perfil's .form/.f idiom (s40e). One guard: an empty
   native date input inside .form needs a min-height or iOS collapses it (the s27
   date-input fix, applied here too). */
.jobform input[type=date] { min-height:44px; }
/* the one-field autosave <form> wraps each input; make it display:contents (like
   .datefld) so it's not a layout box — otherwise it's a min-width:auto flex item and
   a native date input's intrinsic width overflows the 1fr/1fr período grid. */
.jobform .f > form { display:contents; }
.jobform .f2 { gap:12px; }
.jobform .f2 .f, .jobform .f2 input { min-width:0; }
.jobform .f2 input { width:100%; box-sizing:border-box; }

/* THE JOB HEADER SECTION (s43c): ONE section that morphs a form (setup) into a settled
   identity block (locked). The produtora leads as an eyebrow; período + contato are
   first-class rows with real weight; only the nota-fiscal block collapses within. Fields
   stay quiet inline edits (idiom 1): filled reads as display, empty as form. */
.jsec { background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
  box-shadow:0 1px 2px rgba(60,50,35,.04), 0 12px 26px -16px rgba(60,50,35,.16);
  padding:15px 16px; margin:2px 0 14px; }
.jsec-div { border-top:1px solid var(--line); margin:14px -16px; }
.jsec-head { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
.jsec-prod { position:relative; flex:1; min-width:0; margin:0 0 1px; }
/* WYSIWYG (s44): this eyebrow is an INPUT, so it must never text-transform — an
   uppercase render hid the real casing while typing, so "O2 Filmes" could be saved as
   "O2 FILMEs" unseen. True casing now shows here, matching the chip and every card. */
.jsec-eyebrow { font-size:12.5px; font-weight:500; letter-spacing:.04em;
  color:var(--accent); }
.jsec .tt { margin:0; }
.jsec .qtitle { font-size:26px; }
/* Job atual — a corner pill; filled when this is the current job (state as fill). */
.jsec-atualf { flex:none; margin:0; }
.jsec-atual { display:inline-flex; align-items:center; gap:5px; font-size:12px; font-weight:500;
  color:var(--ink-faint); background:transparent; border:1px solid var(--line);
  border-radius:20px; padding:6px 12px; -webkit-appearance:none; appearance:none;
  -webkit-tap-highlight-color:transparent; white-space:nowrap; }
.jsec-atual svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.jsec-atual.on { color:var(--accent); background:var(--tint); border-color:var(--accent); }
.jsec-atual.on svg { fill:currentColor; stroke:none; }
/* First-class rows: an icon, a small label, a strong value. */
.jsec-row { display:flex; align-items:flex-start; gap:11px; }
.jsec-row + .jsec-row { margin-top:13px; }
.jsec-ic { flex:none; width:20px; height:20px; margin-top:1px; color:var(--ink-faint); }
.jsec-ic svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.jsec-field { flex:1; min-width:0; }
.jsec-field > form { display:block; }
.jsec-k { font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 0 1px; }
.jsec-val { font-size:16px; color:var(--ink); }
.jsec-sub { font-size:13.5px; color:var(--ink-soft); margin-top:2px; }
input.jsec-val, input.jsec-sub { display:block; width:100%; border:0; background:transparent;
  padding:0; font-family:inherit; -webkit-appearance:none; appearance:none; }
input.jsec-val::placeholder, input.jsec-sub::placeholder { color:var(--ink-faint); }
button.jsec-periodo-show { display:block; border:0; background:transparent; padding:0;
  text-align:left; font-family:inherit; cursor:text; -webkit-tap-highlight-color:transparent; }
button.jsec-periodo-show.empty { color:var(--ink-faint); }
.jsec-periodo-edit.collapsed { display:none; }
/* Dados fiscais — the only collapse, a <details> inside the section. */
.jsec-fsum { list-style:none; cursor:pointer; display:flex; align-items:center; gap:9px;
  -webkit-tap-highlight-color:transparent; }
.jsec-fsum::-webkit-details-marker { display:none; }
.jsec-fdoc { flex:none; width:18px; height:18px; fill:none; stroke:var(--ink-faint);
  stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
.jsec-ftitle { font-size:14.5px; color:var(--ink); }
.jsec-ftick { color:var(--ok); font-size:13px; }
.jsec-fchev { flex:none; margin-left:auto; width:19px; height:19px; fill:none;
  stroke:var(--ink-faint); stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  transition:transform .18s; }
.jsec-fiscal[open] .jsec-fchev { transform:rotate(180deg); }
.jsec-fbody { padding-top:6px; }
/* Open state (s43f): the summary is the fiscal block's HEADER and its close control, so
   it goes accent when expanded — a pre-attentive "open, tap to close" — with a divider
   under it so the fields read as hanging off it. Closed stays quiet ink. */
.jsec-fiscal[open] .jsec-ftitle { color:var(--accent); }
.jsec-fiscal[open] .jsec-fdoc, .jsec-fiscal[open] .jsec-fchev { stroke:var(--accent); }
.jsec-fiscal[open] > summary.jsec-fsum { border-bottom:1px solid var(--line); padding-bottom:12px; }
.jsec-fiscal[open] .jsec-fbody { padding-top:12px; }
/* Contato (s43i, Option A): the name and the number stack in the field; the .waicon disc
   is anchored to the whole block's vertical centre on the right (align-self overrides the
   row's top-align). The number reads as a quiet sub-line — plain text once locked. */
.jsec-waicon { align-self:center; width:36px; height:36px; }
.jsec-waicon svg { width:19px; height:19px; }
.jsec-wafield { margin-top:2px; }
.jsec-wa-show { display:block; border:0; background:transparent; padding:0; text-align:left;
  font-family:inherit; font-size:13.5px; color:var(--ink-soft); cursor:text;
  -webkit-tap-highlight-color:transparent; }
.jsec-waform { margin-top:4px; }
.jsec-waform.collapsed { display:none; }
.jsec-waform .phonewrap { max-width:none; }
.jsec-waform .phonewrap input { font-size:14px; }

/* The CNPJ magic-fill whisper (s43): narrates the registry fetch, then a verify nudge. */
.cnpjfill { display:none; font-size:12px; margin-top:4px; color:var(--ink-faint); }
.cnpjfill.on { display:block; }
.cnpjfill.ok { color:var(--ok); }

/* NAME-FIRST suggest (s43): the pool's matches under the produtora field — recognition,
   not a form. A floating list she taps to fill everything from one remembered name. */
.prodfield { position:relative; }
.prodsuggest { position:absolute; left:0; right:0; top:100%; z-index:20; margin-top:4px;
  background:var(--card); border:1px solid var(--line); border-radius:12px; overflow:hidden;
  box-shadow:0 12px 30px rgba(40,28,48,.16); }
.prodsuggest-row { display:flex; flex-direction:column; gap:1px; width:100%; text-align:left;
  padding:9px 12px; background:none; border:0; border-top:1px solid var(--line); cursor:pointer;
  -webkit-tap-highlight-color:transparent; }
.prodsuggest-row:first-child { border-top:0; }
.prodsuggest-row:active { background:var(--chip-ok-bg); }
.prodsuggest-row .ps-name { font-size:14px; color:var(--ink); }
.prodsuggest-row .ps-sub { font-size:11.5px; color:var(--ink-faint); }

/* ── Rascunho enxuto (s46): the born-built draft reads as a RECEIPT + one verb.
   Offers instead of ghost rows, the look door in the card header, the commit card
   (signature-first) with the copy chip, and the pedido delta list. */
.addfact { background:none; border:0; font-family:inherit; font-size:12.5px;
  color:var(--ink-faint); padding:2px; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.addfact b { color:var(--ink-soft); font-weight:500; }
.status .addfact { margin-left:2px; }
.rdeal .meta .rcaucao-offer { justify-content:flex-start; padding:6px 0; }
.rmeta-view { background:none; border:0; font-family:inherit; font-size:inherit;
  color:inherit; padding:0; cursor:pointer; text-align:right; }
.ripick-quiet { display:block; text-align:center; padding:12px 0 4px; font-size:13px;
  color:var(--ink-soft); text-decoration:none; }
.mesasec-lbl .ri-lookhd { margin-left:auto; display:inline-flex; align-items:center; gap:5px;
  font-size:12px; font-weight:500; letter-spacing:0; text-transform:none;
  color:var(--ink-faint); text-decoration:none; min-width:0; }
.mesasec-lbl .ri-lookhd svg { width:13px; height:13px; stroke:currentColor;
  stroke-width:1.8; fill:none; flex:none; }
.ri-periodcap { text-align:right; font-size:11px; color:var(--ink-faint); padding:0 0 6px; }
/* The período in the frame (s47g): the deal's WHEN joins the header — quiet,
   tappable, matching the confirmed page's .sub line. */
.tt .rperiod { display:flex; align-items:center; gap:6px; margin-top:3px; }
.tt .rperiod .rperiod-view { text-align:left; font-size:13.5px; color:var(--ink-soft);
  padding:0; }
.tt .rperiod .rpq { display:inline-flex; align-items:center; gap:6px; }
.rcommit { text-align:center; }
.rcommit .sigsend { display:block; }
/* The sourcing brake (s47): the commit card's honest amber line — rede pieces the
   contract would bind that no accepted pedido secures yet. */
.rcommit-warn { display:inline-block; font-size:12.5px; font-weight:600;
  color:var(--chip-warn-ink); background:var(--chip-warn-bg);
  border-radius:var(--r-pill); padding:5px 12px; margin-bottom:12px; }
/* Sourcing coverage (s47): one quiet line per rede owner under the pieces list —
   who the pieces come from, and where their pedido stands. */
.rsourcing { display:flex; flex-direction:column; gap:2px; margin-top:8px;
  padding-top:8px; border-top:1px solid var(--hair); }
.rsrcrow { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.rsrcrow .rsrc { flex:1; }
/* The line's verb (s47b): the one-tap manifest send — amber, chip-shaped, the
   loudest thing on the row exactly because it is the row's true payload. */
.rsrc-pedir button, .rsrc-pedir a { border:0; font-family:inherit; font-size:12px; font-weight:650;
  color:var(--chip-warn-ink); background:var(--chip-warn-bg); text-decoration:none;
  display:inline-block; border-radius:var(--r-pill); padding:5px 13px; cursor:pointer; }
.rsrc-pedir button:active, .rsrc-pedir a:active { filter:brightness(.94); }
.rsrc { display:flex; align-items:center; justify-content:space-between; gap:10px;
  font-size:12px; color:var(--ink-soft); text-decoration:none; padding:3px 0; }
.rsrc-who { display:inline-flex; align-items:center; gap:5px; min-width:0; }
.rsrc-who svg { width:12px; height:12px; stroke:currentColor; stroke-width:1.6;
  fill:none; flex:none; }
.rsrc-st { flex:none; }
.rsrc.ok .rsrc-st { color:var(--ok); }
.rsrc.warn .rsrc-st { color:var(--warn); font-weight:600; }
/* The channel rung's inline field (s47c): the card grows the one missing fact —
   idiom 1 on the cover, no drill-down. */
.tkfield { display:flex; align-items:center; gap:6px; }
.tkfield-in { width:118px; min-width:0; border:0; border-bottom:1px solid var(--line-2);
  background:none; font-family:inherit; font-size:12.5px; color:var(--ink);
  padding:3px 0; border-radius:0; }
.tkfield-in::placeholder { color:var(--ink-faint); }
.tkfield-in:focus { outline:none; border-bottom-color:var(--accent); }
/* The pedir sheet (s47c): the s44 takeover confirm as a bottom sheet — pieces,
   fixed dates, one message field, a real submit. */
.pedsheet-scrim { position:fixed; inset:0; z-index:60; background:var(--overlay);
  display:flex; align-items:flex-end; justify-content:center; }
.pedsheet-card { width:100%; max-width:480px; max-height:82dvh; overflow-y:auto;
  background:var(--card); border-radius:var(--r-sheet) var(--r-sheet) 0 0;
  padding:20px 18px calc(16px + env(safe-area-inset-bottom)); }
.pedsheet-owner + .pedsheet-owner { margin-top:18px; padding-top:16px;
  border-top:1px solid var(--hair); }
.pedsheet-h { font-size:16px; font-weight:650; letter-spacing:-.01em; }
.pedsheet-terms { font-size:12.5px; color:var(--ink-soft); margin-top:2px; }
.pedsheet-list { display:flex; flex-direction:column; gap:8px; margin:12px 0 14px; }
.pedsheet-row { display:flex; align-items:center; gap:10px; }
.pedsheet-th { width:34px; height:45px; flex:none; border-radius:5px; overflow:hidden;
  background:var(--paper-2); display:flex; align-items:center; justify-content:center; }
.pedsheet-th img { width:100%; height:100%; object-fit:cover; display:block; }
.pedsheet-th svg { width:46%; height:46%; stroke:var(--ink-soft); stroke-width:1.2;
  fill:none; opacity:.55; }
.pedsheet-name { font-size:13.5px; min-width:0; }
.pedsheet-msg { width:100%; border:1px solid var(--line); border-radius:var(--r-ctl);
  background:var(--field); font-family:inherit; font-size:13.5px; color:var(--ink);
  padding:10px 12px; margin-bottom:10px; }
.pedsheet-msg::placeholder { color:var(--ink-faint); }
.pedsheet-go { width:100%; }
.pedsheet-cancel { display:block; margin:14px auto 0; border:0; background:none;
  font-family:inherit; font-size:13px; color:var(--ink-soft); cursor:pointer; }
.pedsheet-empty { font-size:13.5px; color:var(--ink-soft); text-align:center;
  padding:8px 0; }
.rcommit-sub { font-size:12.5px; color:var(--ink-soft); margin-top:11px; line-height:1.5; }
.sigcopy { display:inline-flex; align-items:center; gap:6px; margin-top:12px;
  font-size:12.5px; color:var(--accent); background:var(--tint); border:0;
  border-radius:var(--r-pill); padding:7px 14px; font-family:inherit; cursor:pointer; }
.sigcopy svg { width:13px; height:13px; stroke:currentColor; stroke-width:1.8; fill:none; }
.sigcopy:active { background:var(--tint-2); }
.rcommit-altform { margin-top:14px; }
.rcommit-alt { background:none; border:0; font-family:inherit; font-size:13.5px;
  color:var(--ink-soft); text-decoration:underline; text-decoration-color:var(--line-2);
  text-underline-offset:3px; cursor:pointer; }
.rdiff-lead { font-weight:600; margin-bottom:5px; }
.rdiff { margin:0; padding-left:18px; }
.rdiff li { margin:2px 0; }
.rdiffbox .cb-foot { display:block; margin-top:7px; }
.rdetail [hidden] { display:none !important; }

/* ── The verb pill + action section (s46): when the ball is hers the card SAYS the
   next move — the loudest readable mark on it — and moves up into Precisa de você. */
.cardstage.verb { background:var(--warn); color:#FFFDF8; font-weight:600;
  font-size:11.5px; letter-spacing:.02em; }
.acaolist { margin-bottom:26px; }
.inbox + .acaolist { margin-top:10px; }

/* ── Zona verde + tickets (s46c, the color law): color carries WHOSE MOVE IT IS —
   red a-date-broke, amarelo sua-vez, verde cuidado-por-agora (the FIELD: generous,
   alarms pop as figures against it), cinza inert, roxo never status. Action cards
   are compact tickets (photo · gold verb · one number); resting work is thin ✓ rows
   inside one continuous green zone per lane. */
.tkwrap { position:relative; margin-bottom:10px; }
.tkcard { position:relative; display:flex; align-items:center; gap:12px; overflow:hidden;
  background:var(--card); border:1px solid var(--line); border-radius:14px;
  padding:10px 14px 10px 14px; text-decoration:none; color:var(--ink);
  -webkit-tap-highlight-color:transparent; }
.tkcard::before { content:""; position:absolute; left:0; top:0; bottom:0; width:4px;
  background:var(--warn); }
.tkcard.late { background:var(--chip-alert-bg); border-color:transparent; }
.tkcard.late::before { background:var(--danger); }
.tkth { width:52px; height:69px; flex:none; border-radius:5px; overflow:hidden;
  background:var(--paper-2); display:grid; place-items:center; }
.tkth img { width:100%; height:100%; object-fit:cover; display:block; }
.tkth svg { width:46%; height:46%; stroke:var(--ink-soft); stroke-width:1.2; fill:none; opacity:.55; }
.tkmid { flex:1; min-width:0; }
.tkverb { display:block; font-size:15px; font-weight:700; letter-spacing:-.01em;
  color:var(--warn); }
.tkcard.late .tkverb { color:var(--danger); }
.tkname { display:block; font-size:12.5px; color:var(--ink-soft); margin-top:3px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tknum { flex:none; font-size:14.5px; font-weight:600; font-variant-numeric:tabular-nums;
  white-space:nowrap; }
.tkcard.late .tknum { color:var(--danger); }
.tkwrap .hold-ring { position:absolute; right:10px; top:50%; margin-top:-22px; border-radius:50%; }

/* ── s48 base tier: the contracts list (trabalhos_base.html) — one flat card idiom:
   thumb · client · dates · value · ONE state word. Everything else the dense room
   renders (lanes, ladders, verb pills, tickets) belongs to the Estúdio tier. */
.ctr-summary { font-size:13.5px; color:var(--ink-soft); margin:14px 2px 6px; }
.ctr-summary b { color:var(--ink); font-weight:700; }
.ctrwrap { position:relative; margin-bottom:9px; }
.ctrwrap .ctrcard { margin-bottom:0; }
.ctrwrap.holding .hold-ring { display:flex; background:rgba(40,28,48,.06); border-radius:14px; }
.ctrwrap .hold-ring .trk { stroke:rgba(60,50,35,.18); }
.ctrwrap .hold-ring .prg { stroke:var(--accent); }
.ctrcard { display:flex; align-items:center; gap:12px; background:var(--card);
  border:1px solid var(--line); border-radius:14px; padding:11px 14px;
  margin-bottom:9px; text-decoration:none; color:var(--ink);
  box-shadow:0 1px 3px var(--shadow); -webkit-tap-highlight-color:transparent; }
.ctrcard:active { transform:translateY(1px); }
.ctrcard.done { opacity:.62; box-shadow:none; }
.ctrth { width:44px; height:58px; flex:none; border-radius:5px; overflow:hidden;
  background:var(--paper-2); display:grid; place-items:center; }
.ctrth img { width:100%; height:100%; object-fit:cover; display:block; }
.ctrth svg { width:46%; height:46%; stroke:var(--ink-soft); stroke-width:1.2; fill:none; opacity:.55; }
.ctrmid { flex:1; min-width:0; }
.ctrttl { display:block; font-size:14.5px; font-weight:600; letter-spacing:-.01em; }
.ctr-teste { font-style:normal; font-size:11px; color:var(--ink-faint);
  border:1px dashed var(--line-2); border-radius:999px; padding:1px 7px;
  margin-left:5px; vertical-align:1px; }
.ctrsub { display:block; font-size:12.5px; color:var(--ink-soft); margin-top:3px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ctrword { font-weight:600; }
.ctrword.ok { color:var(--chip-ok-ink); }
.ctrword.warn { color:var(--warn); }
.ctrword.dim { color:var(--ink-faint); font-weight:500; }

.gzone { background:var(--chip-ok-bg); border-radius:18px; padding:4px 10px 10px;
  margin-top:6px; }
.gzone .enggrp.gok { color:var(--chip-ok-ink); margin:10px 2px 10px; display:flex;
  align-items:center; gap:7px; }
.gzone .enggrp.gok .dot { width:6px; height:6px; border-radius:50%; background:var(--ok); flex:none; }
.glinewrap { position:relative; margin-bottom:8px; }
.glinewrap:last-child { margin-bottom:2px; }
.gline { display:flex; align-items:center; gap:11px; background:var(--card);
  border-radius:12px; padding:10px 12px; text-decoration:none; color:var(--ink);
  -webkit-tap-highlight-color:transparent; }
.gth { width:40px; height:53px; flex:none; border-radius:5px; overflow:hidden;
  background:var(--paper-2); display:grid; place-items:center; }
.gth img { width:100%; height:100%; object-fit:cover; display:block; }
.gth svg { width:46%; height:46%; stroke:var(--ink-soft); stroke-width:1.2; fill:none; opacity:.55; }
.gmid { flex:1; min-width:0; }
.gname { display:block; font-size:14px; font-weight:550; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.gsub { display:block; font-size:12px; color:var(--ink-soft); margin-top:3px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.gchk { flex:none; color:var(--chip-ok-ink); display:inline-flex; }
.gchk svg { width:15px; height:15px; stroke:currentColor; stroke-width:2.4; fill:none; }
.glinewrap .pcardx { position:absolute; right:42px; top:50%; transform:translateY(-50%); }
.glinewrap .hold-ring { position:absolute; right:8px; top:50%; margin-top:-22px; border-radius:50%; }

.clearhero { background:var(--chip-ok-bg); border-radius:18px; padding:26px 18px;
  text-align:center; margin:2px 0 20px; }
.clearhero .big { font-size:19px; font-weight:750; color:var(--chip-ok-ink);
  display:flex; align-items:center; justify-content:center; gap:9px; }
.clearhero .big svg { width:22px; height:22px; stroke:currentColor; stroke-width:2.6; fill:none; }
.clearhero p { margin-top:8px; font-size:12.5px; color:var(--chip-ok-ink); opacity:.8; }

/* ── Card-fireable verbs + the sign ladder (s46d): actions fire where the terms
   are — event stamps and WhatsApp doors on the ticket, quiet levers on green lines,
   the delta riding a changed pedido's card, and the Enviou? attestation. */
.tkcard { padding:0; }
.tkmain { flex:1; min-width:0; display:flex; align-items:center; gap:12px;
  padding:10px 0 10px 14px; text-decoration:none; color:inherit;
  -webkit-tap-highlight-color:transparent; }
.tkright { flex:none; display:flex; flex-direction:column; align-items:flex-end;
  gap:7px; padding:10px 14px 10px 4px; }
.tkact { display:inline-flex; align-items:center; gap:5px; font-size:12px;
  font-weight:600; color:var(--warn); background:none;
  border:1.5px solid var(--warn); border-radius:var(--r-pill); padding:5px 11px;
  font-family:inherit; cursor:pointer; text-decoration:none; white-space:nowrap;
  -webkit-tap-highlight-color:transparent; }
.tkact svg { width:13px; height:13px; stroke:currentColor; stroke-width:1.8; fill:none; }
.tkcard.late .tkact { color:var(--danger); border-color:var(--danger); }
.tkactform { display:contents; }
.tkdiff { display:block; margin-top:4px; font-size:11.5px; color:var(--ink-soft); }
.tkdiff span { display:inline-block; background:var(--paper-2); border-radius:6px;
  padding:2px 7px; margin:2px 4px 0 0; }
.tkcard.late .tkdiff span { background:rgba(255,255,255,.5); }
.glinewrap.hasact .gline { padding-right:8.5em; }
.gact { position:absolute; right:40px; top:50%; transform:translateY(-50%); }
.gact button { font-size:11.5px; font-weight:600; color:var(--ink-soft);
  background:none; border:1px solid var(--line-2); border-radius:var(--r-pill);
  padding:4px 10px; font-family:inherit; cursor:pointer; white-space:nowrap; }
.rcommit-q { font-size:16px; font-weight:650; letter-spacing:-.01em; margin-bottom:13px; }
.rcommit-yesform { margin-bottom:2px; }
.rcommit .sigcopy { text-decoration:none; }

/* s49 — the borrower's pay rail: the Pix copia-e-cola reads as one copyable block */
.paycard { margin-top:14px; }
.paycard .pixcopy { width:100%; margin:4px 0 8px; }
.paycard .pixcopy .siglink-url { white-space:normal; text-overflow:clip; word-break:break-all; font-size:12px; line-height:1.35; max-height:3.9em; overflow:hidden; }
.paycard .btn.primary { width:100%; margin-top:8px; }
.faturar { margin-top:12px; }
.faturar .faturar-form { display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.faturar .faturar-form .btn { align-self:flex-start; }

/* s49 — the locked Trabalhos room on tier 1: porta fechada (the room's furniture, ghosted) */
.portafechada { margin-top:26px; }
.ghostcards { position:relative; display:flex; flex-direction:column; gap:10px; }
.ghostcard { display:flex; align-items:center; gap:12px; background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-card); padding:12px 14px; }
.ghostcard:nth-child(1) { opacity:.55; } .ghostcard:nth-child(2) { opacity:.4; } .ghostcard:nth-child(3) { opacity:.25; }
.ghostthumb { width:52px; height:69px; border-radius:10px; background:var(--paper-2); flex:none; }
.ghostlines { display:flex; flex-direction:column; gap:7px; flex:1; }
.ghostlines i { display:block; height:12px; border-radius:6px; background:var(--line); }
.ghostlines i.l2 { height:10px; background:var(--paper-2); }
.ghostlines i.l3 { height:10px; } .ghostlines i.ok { background:var(--chip-ok-bg); } .ghostlines i.warn { background:var(--chip-warn-bg); }
.ghostfade { position:absolute; left:0; right:0; bottom:-6px; height:120px; pointer-events:none;
  background:linear-gradient(180deg, color-mix(in srgb, var(--paper) 0%, transparent) 0%, var(--paper) 100%); }
.studiolbl { margin-top:6px; margin-bottom:0; }
.studiosoon-word { color:var(--ink-faint); font-weight:500; letter-spacing:.06em; text-transform:none; }
.studiopitch { margin:12px 0 0; font-size:15px; line-height:1.5; color:var(--ink-soft); }
.studioteaser-foot { text-align:left; margin:16px 0 0; font-size:13px; }

/* s49 — the rede piece page: one green door, the buy door, the style offer, the shelf chips */
.btn.wabuy { color:var(--wa); border-color:var(--wa); background:var(--paper); max-width:none; margin-top:10px; }
.btn.wabuy:active { background:var(--paper-2); }
.pedircard .redewa svg { width:17px; height:17px; vertical-align:-3px; margin-right:6px; }
.askstyle { display:flex; align-items:center; justify-content:space-between; gap:10px; margin:-4px 0 12px;
  font-size:13px; color:var(--ink-soft); }
.askstyle button { flex:none; font:inherit; font-weight:600; color:var(--accent); background:none; border:none; padding:6px 0; cursor:pointer; }
.tile .tile-sale { position:absolute; right:6px; bottom:6px; z-index:2; font-size:10px; font-weight:700; letter-spacing:.04em;
  border-radius:999px; padding:2px 8px; background:var(--chip-ok-bg); color:var(--chip-ok-ink); }
.tile .tile-sale.sold { background:var(--paper-2); color:var(--ink-soft); }

/* s49 — the three-section ticket in the share sheet ([hidden] must beat the display rules) */
.txtsheet-ticket[hidden], .txtsheet-mark[hidden], .txtsheet-facts[hidden] { display:none; }
.txtsheet-ticket { display:flex; align-items:center; justify-content:center; height:240px; margin:0 0 12px; border-radius:12px; background:var(--paper-2); overflow:hidden; }
.txtsheet-ticket img { display:block; height:100%; width:auto; max-width:100%; object-fit:contain; }
.txtsheet-field { position:relative; }
.txtsheet-field .txtsheet-input { padding-right:44px; }
.txtsheet-mark { position:absolute; top:8px; right:8px; width:32px; height:32px; display:grid; place-items:center;
  background:none; border:none; padding:0; cursor:default; color:var(--ink-faint); }
.txtsheet-mark svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linejoin:round; }
.txtsheet-mark.is-dirty { color:var(--accent); cursor:pointer; }
.txtsheet-mark.is-dirty svg { fill:color-mix(in srgb, var(--accent) 18%, transparent); }
.txtsheet-saved { margin:8px 2px 0; font-size:13px; font-weight:600; color:var(--ok); }
.txtsheet-saved[hidden], .txtsheet-confirm[hidden] { display:none; }
.txtsheet-confirm { margin:10px 0 0; padding:14px 14px 12px; background:var(--card); border:1px solid var(--line); border-radius:var(--r-ctl); display:flex; flex-direction:column; gap:4px; }
.txtsheet-confirm b { font-size:15px; }
.txtsheet-confirm small { font-size:13px; color:var(--ink-soft); }
.txtsheet-confirm small:empty { display:none; }
.txtsheet-confirm-actions { display:flex; justify-content:flex-end; gap:16px; margin-top:8px; }
.txtsheet-confirm-actions button { font:inherit; font-size:14px; font-weight:600; background:none; border:none; padding:6px 0; cursor:pointer; color:var(--ink-soft); }
.txtsheet-confirm-actions #shareConfirmYes { color:var(--accent); }
.txtsheet-facts { margin:12px 0 0; padding:12px 14px; font-family:var(--sans); font-size:13.5px; line-height:1.5; color:var(--ink-soft);
  white-space:pre-wrap; word-break:break-word; background:var(--paper-2); border-radius:var(--r-ctl); }
/* s49 — the payer row on the rede card */
.payerfld { margin:16px 0 11px; }   /* s60 — breathing room above 'Nota em nome de' (was crammed under the dates) */
.payerfld select { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:15px; padding:11px 12px; border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--field); color:var(--ink); }
.payerother { display:flex; flex-direction:column; gap:8px; margin:0 0 11px; }
.payerother[hidden] { display:none; }
.payerother input { width:100%; box-sizing:border-box; font-family:var(--sans); font-size:15px; padding:11px 12px; border:1px solid var(--line-2); border-radius:var(--r-ctl); background:var(--field); color:var(--ink); }
/* s49 — ticket mode: the send continues the green + bubble of the tap that opened it */
.txtsheet.is-ticket .txtsheet-go { background:var(--wa); border-color:#25613E; color:#FBF7F0; display:inline-flex; align-items:center; justify-content:center; gap:6px; }
.txtsheet.is-ticket .txtsheet-go svg { width:17px; height:17px; }
/* THE LOOK CARD in the sheet (s49): the card is the payload, shown as itself; under it
   the textarea is her NOTE — empty, a placeholder, rides as the caption when written. */
.txtsheet-card[hidden] { display:none; }
.txtsheet.is-card .txtsheet-input { min-height:56px; }
.txtsheet.is-card .txtsheet-input::placeholder { color:var(--ink-faint); }
/* s70: the slot holds the card's 4:5 FOOTPRINT from the first frame (capped at the same 44vh
   the image respects), so the sheet opens at its final height — no bottom-half-then-image jump.
   The image fades in over the tinted slot as its bytes arrive. */
.txtsheet-card { display:flex; justify-content:center; margin:0 0 12px; padding:10px; border-radius:12px; background:var(--paper-2); }
/* width-driven: full slot width, capped so a 4:5 box never exceeds 44vh tall — the ratio gives
   the height BEFORE any bytes arrive, so the box is there from the first frame. */
.txtsheet-card img { display:block; width:100%; max-width:calc(44vh * 0.8); aspect-ratio:4/5; height:auto; border-radius:6px; box-shadow:0 3px 12px rgba(20,16,10,.18);
  opacity:0; transition:opacity .18s ease-out; }
.txtsheet-card img.is-in { opacity:1; }
/* a plain PHOTO share (s70): the slot wears the hero's 2:3 (the framed crop that leaves);
   `auto 2/3` = the box before bytes, the photo's own ratio once loaded (other plain shares). */
.txtsheet.is-photo .txtsheet-card img { aspect-ratio:auto 2/3; max-width:calc(44vh * 2 / 3); }
/* the look SHARE is the content-height pitch card (s80 — 'hug the render'): no fixed page any
   more, so `auto 112/180` gives a sensible 3:4-render footprint before bytes, then snaps to the
   render's TRUE ratio once loaded (a 2:3 render is taller, a wide one shorter). Height-budgeted
   (~54vh) so the card still clears the recado field + buttons; width follows from the ratio. */
.txtsheet.is-card .txtsheet-card img { aspect-ratio:auto 112/180; max-width:calc(54vh * 112 / 180); }
.txtsheet-card img[src=""] { display:none; }
.txtsheet-confirm-reset { margin-right:auto; color:var(--ink-faint) !important; font-weight:500 !important; }
.txtsheet-confirm-reset[hidden] { display:none; }
.txtsheet-actions a.txtsheet-go { flex:1; box-sizing:border-box; text-align:center; text-decoration:none; font-family:var(--sans); font-size:14px; font-weight:500; border-radius:var(--r-ctl); padding:12px; }
.txtsheet-actions a.txtsheet-go[hidden], .txtsheet-actions #shareGo[hidden] { display:none; }
/* s49 — the payer select wears the app's field, not the OS's (appearance off + own chevron) */
.payerfld select { -webkit-appearance:none; appearance:none; padding-right:36px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E6674' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat:no-repeat; background-position:right 12px center; background-size:16px 16px; }
/* s49 — the look's ticket card on the grid (base): the sheet's dress, inline */
.lticket { margin-top:12px; background:var(--card); border:1px solid var(--line); border-radius:var(--r-card); padding:14px; }
.lticket[hidden] { display:none; }
.lticket .txtsheet-facts { margin-top:10px; }
.lticket .txtsheet-actions { margin-top:12px; }
.lticket .txtsheet-actions a.txtsheet-go { background:var(--wa); border:1px solid #25613E; color:#FBF7F0; display:inline-flex; align-items:center; justify-content:center; gap:6px; }
.lticket .txtsheet-actions a.txtsheet-go svg { width:17px; height:17px; }
/* s49 — the spotlight: the Peças+Origem wrapper above a scrim over the rest of the page (s60:
   lifts the wrapper so the grid card AND the composer card ride the spotlight as one) */
.ticket-scrim { position:fixed; inset:0; z-index:60; background:var(--overlay); }
.ticket-scrim[hidden] { display:none; }
.lookblock.ticket-lit, #lookSourceWrap.ticket-lit { position:relative; z-index:61; }
/* s49 — you on the rede's ladder: a marker row at your rank, a door to your vitrine */
.shopcard.shopcard-me { background:var(--tint); margin:18px 0 6px; border-radius:var(--r-card);
  border:none; box-shadow:inset 0 0 0 1px var(--line-2), 0 6px 22px var(--shadow); }   /* the frame marks YOU; roster cards go frameless. s83: an INSET ring, not a border — a border took 1px and shifted this card's avatar + text off the column the roster cards share */
/* s58 — YOUR real member card: the inner link carries face+meta (the same row a roster card
   is), with the on/off toggle as its sibling so the toggle isn't nested inside the link. The
   toggle's position already shows on/off, so no separate live dot (s58 redesign). */
.shopcard-melink { flex:1; min-width:0; display:flex; align-items:center; gap:13px; text-decoration:none; color:inherit; }
/* OFF the rede (s59): the SAME 104px card, face dimmed so it reads 'you, paused' — the box,
   border and toggle stay full so nothing reflows or loses its tap target. The why+fix ride
   the caption below (.redeself-off), replacing the old shorter status strip. */
.shopcard-me.shopcard-off .shopcard-melink { opacity:.45; filter:grayscale(.55); }
.redeself-off { display:flex; align-items:flex-start; gap:8px; margin:8px 2px 2px; }
.redeself-eye { flex:none; width:19px; height:19px; margin-top:1px; }
.redeself-eye svg { width:19px; height:19px; stroke:var(--ink-faint); fill:none; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.redeself-msg { font-size:12.5px; line-height:1.4; color:var(--ink-soft); }
.redeself-msg b { color:var(--ink); font-weight:600; }
/* s49 — the vitrine's identity is the door to Perfil (no pencil on top of it) */
a.vphoto-door { text-decoration:none; color:#FBF7F0; }   /* s82: cream initial, same as the loja disc */
.vname-door { color:inherit; text-decoration:none; }
.shopcard { height:104px; box-sizing:border-box; }   /* the one shape (s50): 4 lines + 14px padding */
/* s49 — sale state lives on the tile's fact line, never on the photo */
/* s50 (his call): the green TAG GLYPH alone, no word — the word took the room and bent
   the cards at small sizes; the glyph is learned from the acervo's 'à venda' button and
   the rede piece page says it in full. The word stays for screen readers only. */
.vcap-sale, .sb-sale { display:inline-flex; align-items:center; font-style:normal; color:var(--ok); vertical-align:-1px; }
.vcap-sale .saletag, .sb-sale .saletag { width:13px; height:13px; fill:currentColor; stroke:none; }
.sb-sold { display:inline-block; font-style:normal; font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:none;
  background:var(--paper-2); color:var(--ink-soft); border-radius:6px; padding:2px 7px; vertical-align:1px; }
.vtile-sale, .tile .tile-sale { display:none; }
/* s49 — the rede card's fork: Alugar | Comprar, one decision then one action */
.fork { display:flex; gap:6px; margin:0 0 12px; background:var(--paper-2); border-radius:var(--r-ctl); padding:4px; }
.fork-btn { flex:1; font:inherit; font-size:14px; font-weight:600; padding:9px 8px; border:none; border-radius:9px; background:none; color:var(--ink-soft); cursor:pointer; }
.fork-btn.on { background:var(--card); color:var(--ink); box-shadow:0 1px 2px var(--shadow); }
.fork-buy[hidden], .fork-rent[hidden] { display:none; }
.fork-buyline { margin:2px 0 12px; font-size:15px; color:var(--ink-soft); }
.fork-buyline b { color:var(--ink); }
/* the footer with a chip: size and chip sit side by side on one baseline — no dangling dot */
/* block flex, centred: a lone chip (no size — socks, hats) sits in the middle, never left (s49) */
.vcap.has-chip, .tile .sb.has-chip { display:flex; align-items:center; justify-content:center; gap:7px; }
.vcap.has-chip .vcap-sale, .tile .sb.has-chip .sb-sale, .tile .sb.has-chip .sb-sold { vertical-align:baseline; }
/* s49 — a standalone active chip (no × cap) keeps both round ends; the row breathes under Destaques */
.fchip.on.fchip-solo { border-radius:20px; }
.vchips { margin-top:12px; }
.redesec-n { letter-spacing:.06em; color:var(--ink-faint); font-weight:600; }
/* s49 — VALORES: the ficha's money as ONE card, two cells (ALUGUEL · VENDA). Caps label
   over a big number, R$ + unit small, a foot line; the empty Venda cell is the dashed offer.
   Numbers are .qedit quiet edits sized to content (data-fit). Replaces the loose money line. */
.valores { display:flex; gap:6px; padding:6px; margin-top:10px; background:var(--card);
  border:1px solid var(--line-2); border-radius:16px; }
/* s75 Option B (his pick): each posture is a cell — label + the number in a REAL bordered
   field (the ficha's "A peça" input idiom, not a loose inline number), and the "✓ salvo"
   flash lands at the cell's TOP-RIGHT (next to the label), never over it. */
.valcell { flex:1; min-width:0; position:relative; display:flex; flex-direction:column; gap:6px; padding:10px 12px; border-radius:12px;
  text-align:left; font-family:inherit; color:var(--ink); background:none; border:0; }
.valcell.valcell-offer { border:1px dashed var(--line-2); justify-content:center; gap:8px; cursor:pointer; }
.valcell.valcell-offer:active { background:var(--tint); }
.val-div { flex:none; width:1px; background:var(--line); margin:8px 0; }
.val-k { font-size:10.5px; letter-spacing:.11em; text-transform:uppercase; color:var(--ink-faint); font-weight:600; }
/* the field = a soft panel (the --field fill, NO hairline), EXACTLY like the "A peça" value
   boxes above it (border:0, his 'less like a form' call). */
.val-v { display:flex; align-items:baseline; gap:5px; flex-wrap:wrap; font-variant-numeric:tabular-nums;
  background:var(--field); border:0; border-radius:10px; padding:9px 12px; }
[data-theme="dark"] .val-v { background:color-mix(in srgb, var(--card), var(--ink) 7%); }
.val-v .qfield { flex:none; align-items:baseline; gap:5px; position:static; }   /* salvo escapes to the cell */
.valcell .qfield .inline-saved { position:absolute; top:10px; right:12px; left:auto; margin:0; }
.val-r { font-size:13px; color:var(--ink-faint); font-weight:500; }
.val-n { font-size:20px; font-weight:600; letter-spacing:-.01em; line-height:1.1; color:var(--ink); }
/* the "só à venda" cull: no real value, so no field box — just a quiet line */
.val-v:has(.val-off) { background:none; padding:0; }
.val-n.val-off { font-size:15px; font-weight:500; color:var(--ink-faint); }   /* s58 — não aluga */
/* the number INPUT fills the field — no box-in-box: it owns no border/fill of its own, even
   on focus (the .val-v soft panel is the field), matching A peça's .v.vq .qedit. */
.val-v .qedit.val-n, .val-v .qedit.val-n:focus { border:0; background:transparent; box-shadow:none;
  width:3ch; min-width:2ch; max-width:8ch; margin:0; padding:0; text-align:left; line-height:1.1; }
.val-unit { font-size:13px; color:var(--ink-soft); font-weight:500; }
.val-unit .ed { font-size:13px; }
.val-foot { font-size:12px; color:var(--ink-faint); min-height:15px; }
.val-foot .ml-form { display:inline; }
.val-foot .saleundo { padding:0; font-size:12px; color:var(--ink-soft); }
.val-offer { display:flex; align-items:center; gap:6px; font-size:14px; font-weight:500; color:var(--accent); }
.val-plus { font-size:18px; line-height:1; }

/* IDENTITY MASTHEAD (s52c): categoria + name + época + swatches were loose text on the
   paper while everything below became cards — a Gestalt miss. They get their own card,
   the job-page masthead idiom. The name stays a big title (not a field); the eyebrow
   (categoria) sits tight over it, época below, swatches at the foot. */
/* s52f — the card box squeezed the title; the identity reads as a masthead on the paper.
   s52j — categoria/época left the masthead, so it's just the name + swatches now. */
.piece-detail .fichamast { padding:0; margin:22px 0 4px; }   /* gap below the CTA = gap above it, so the CTA sits equidistant between thumbs and title (s52l) */
/* s52l — the CTA sits equidistant between the thumbs and the title (the top gap comes
   from .tt's own margin). The button's own look is the shared .mesalink--pin (s52p). */
.piece-detail .thumbs { margin-bottom:0; }
.piece-detail .fichamast .qtitle-form, .piece-detail .fichamast > h1 { margin-top:1px; }
.piece-detail .fichamast .swatches { margin-top:13px; }
.piece-detail .fichamast .swlock { margin-top:4px; }
/* s52k, his call — center the identity to match the rede piece page (same object, both
   views): name + swatches + status centered; the CTA above and the field sections below
   stay left. text-wrap:balance evens a multi-line name (the common case). */
.piece-detail .fichamast { text-align:center; }
.piece-detail .fichamast .fichaname-q,
.piece-detail .fichamast > h1 { text-align:center; text-wrap:balance; }
.piece-detail .fichamast .swatches { justify-content:center; }
.piece-detail .status { justify-content:center; }

/* FICHA SECTIONS (s52): the loose .meta ledger grouped into named cards, the same
   idiom as the job page's .jsec and O Controle. The card supplies the grouping the
   hairline ledger never did; rows keep their exact edit wiring, only the borders move
   inside the card (a line BETWEEN rows, never at the card's own edges). */
.piece-detail .fsec { background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
  box-shadow:0 1px 2px rgba(60,50,35,.04), 0 12px 26px -18px rgba(60,50,35,.16);
  padding:2px 16px 8px; margin:14px 0; }
.piece-detail .fsec-h { font-size:11px; font-weight:600; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent); padding:13px 0 3px; }
/* Etiquetas card (s72, his call): spotlighted in LIGHT PLUM — the free, searchable words the owner
   adds in her own language get a first-class card, right after identity. The tag pills stay exactly
   as they are (rectangular, 2px); the '+ etiqueta' matches their shape, dashed + plum to read as an add. */
.piece-detail .fsec-tags { border-color:color-mix(in srgb, var(--accent) 38%, var(--line));
  background:color-mix(in srgb, var(--accent) 6%, var(--card)); }
.piece-detail .fsec-tags .tags { margin-top:10px; }
.piece-detail .tagadd { font-size:12px; color:var(--accent); border:1px dashed color-mix(in srgb, var(--accent) 50%, var(--line-2));
  border-radius:2px; padding:5px 12px; background:none; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.piece-detail .fsec-note { font-size:12px; color:var(--ink-soft); margin:10px 0 2px; }
/* THE FIELD TREATMENT (s52b, his call — the Perfil parallel): each row is two columns
   (label left, value right), and the value sits in a cream --field box (brighter than
   the card) with a hairline. The box surface IS the editability affordance — no marker,
   no hint — and its single min-height makes every row the same height regardless of the
   value's kind (inline input, .ed span, or size button). No hairlines between rows: the
   boxes carry the separation. */
.piece-detail .fsec .row { display:grid; grid-template-columns:92px 1fr; gap:12px;
  align-items:center; border:none; padding:5px 0; }
.piece-detail .fsec .row .k { font-size:11px; letter-spacing:.06em; white-space:nowrap; }
.piece-detail .fsec .row .v { display:flex; align-items:center; justify-content:flex-start;
  gap:7px; width:100%; box-sizing:border-box; min-height:40px; padding:9px 12px; text-align:left;
  font-size:15px; font-weight:400; color:color-mix(in srgb, var(--ink), var(--ink-soft) 20%);
  background:var(--field); border:0; border-radius:10px; }
/* s52d, his call — 'make it look less like a form': no hairline; the lighter fill alone
   reads as a soft panel. Dark's --field sits at card level, so the box gets a lifted fill
   there to stay visible without a border. */
[data-theme="dark"] .piece-detail .fsec .row .v { background:color-mix(in srgb, var(--card), var(--ink) 7%); }
/* s52e, his call — ONE type for every value (target = 'onde guarda' = 15px/500): the .v
   rule above sizes all of them; the variants below (input, size button) are pulled to
   match. Empties are one quiet grey add-prompt (was a mix of ink/plum/grey). No focus
   ring on edit (his call) — the caret and the opened sheet are the feedback. */
.piece-detail .fsec .row .v.emptyfield,
.piece-detail .fsec .row .v .ed.emptyfield { color:var(--ink-faint); font-weight:400; opacity:1; }
/* WARN (#32, s52j): categoria 'Outro'/blank + época blank — the fields the AI most often
   gets wrong. Now that they're field boxes (moved down from the masthead), the box itself
   turns red-dashed so a half-classified piece can't slip past. Overrides the plain box. */
.piece-detail .fsec .row .v.warnfield { color:var(--danger); font-weight:500;
  background:color-mix(in srgb, var(--danger) 7%, var(--field));
  border:1px dashed color-mix(in srgb, var(--danger) 45%, transparent); }
/* Tipo/Marca: the inline input fills the box — the box owns the border/bg, the input
   goes transparent and left-aligned (never a box-in-box). */
.piece-detail .fsec .row .v.vq { padding:0; justify-content:flex-start; }
.piece-detail .fsec .row .v.vq .qfield { flex:1; min-width:0; }
.piece-detail .fsec .row .v.vq .qedit { width:100%; margin:0; padding:8px 12px;
  text-align:left; border:0; background:transparent; line-height:1.3;
  font-size:15px; font-weight:400; color:inherit; }   /* 15/400, softened ink — matches every value */
.piece-detail .fsec .row .v.vq .qedit:focus { border:0; background:transparent; }
.piece-detail .fsec .row .v.vq .inline-saved { top:50%; transform:translateY(-50%);
  right:10px; background:var(--field); padding-left:6px; }
/* the size/measures buttons are already .v — flatten their internal alignment to the box */
.piece-detail .fsec .row .v.measures { flex-wrap:wrap; gap:5px 10px; cursor:pointer; font-size:15px; font-weight:400; }
.piece-detail .fsec .row .v.measempty { cursor:pointer; color:var(--ink-faint); font-weight:400; }
.piece-detail .fsec .row .v .mv { color:inherit; }   /* the size value takes the softened ink, not pure --ink */
.piece-detail .fsec .row .v .medido { margin-left:auto; }
/* the .ed inside a value box (Cor) is inline text, not its own box */
.piece-detail .fsec .row .v .ed { background:none; }
/* Etiquetas = a SET, read in parallel — a chip cloud, not a value box crushed to a count
   (s52 S/N: the instant-read fix). Sits below the last row with a little air. */
.piece-detail .fsec .fsec-chips { padding:4px 0; margin-top:8px; }
.piece-detail .fsec .fsec-chips-k { display:block; font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-faint); margin-bottom:9px; }
.piece-detail .fsec .fsec-chips .tags { margin-top:0; }

/* PHOTO STRIP — cleaner (s52h, his call): the type label (IA / ETIQUETA / REF) moves OFF
   the image into a caption below it — the same idiom as the gallery tile's size band — so
   the image, the payload, reads clean. Each labeled thumb becomes a mini-card (image +
   caption); plain photos stay a pristine image. The cover/order discs stay ON the image
   (they're state, toggled in Fotos-pra-rede mode) but softened so the plum is less intense. */
.piece-detail .thumbs { align-items:flex-start; }
.piece-detail .thumbs .thumb { display:flex; flex-direction:column; aspect-ratio:auto; }
/* the image sits in a fixed 2:3 box and FILLS it (height:100%) — the proven pre-s52h
   behaviour; relying on aspect-ratio on the <img> itself let some renders size wrong on
   iOS (s52i bug). The caption (.sb) is a sibling below the box. */
.piece-detail .thumbs .thumb .timg { width:100%; aspect-ratio:2/3; overflow:hidden; display:block; }
.piece-detail .thumbs .thumb .timg img { width:100%; height:100%; object-fit:cover; display:block; }
.piece-detail .thumbs .thumb.thumbadd { display:grid; place-items:center; aspect-ratio:2/3; }
.piece-detail .thumbs .thumb .sb { width:100%; box-sizing:border-box; text-align:center; padding:4px 3px;
  font-size:8.5px; font-weight:700; letter-spacing:.03em; text-transform:uppercase; line-height:1.25;
  color:var(--ink-soft); background:var(--paper-2); }   /* solid grey — was --ink-faint, read as washed (s52i) */
.piece-detail .thumbs .thumb .sb.ia { color:var(--accent); }
.piece-detail .thumbmark { opacity:1; }   /* s72 (his call): the white-disc badge is fully opaque — the .78 softening was for the old solid-plum dot */

/* s49 — SELECT MODE on the own grid (D): 'selecionar' on the Peças line, plum rings, the
   two-verb bar (the looks' .bookbar dress). body.selecting: hold-delete + Mesa pin sleep. */
/* venda is GREEN everywhere (s49): the door wears the price-tag glyph + the words */
/* the Peças-row à-venda button = the SAME green tag glyph the for-sale pieces wear, ringed
   by a thin green circle (s62, his call), the mesa-pin size (22px, 13px glyph). */
.acsel-open { display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
  border:1.5px solid var(--ok); border-radius:50%; background:transparent; padding:0; cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.acsel-open:active { background:color-mix(in srgb, var(--ok) 14%, transparent); }
.acsel-open svg { width:13px; height:13px; }
/* Select-to-sell (s62, toggle-in-place): tapping a piece flips its green tag right on the bottom
   band — no corner badge, no struck state, no verb labels. The .selbadge / off-button / green-go
   styles retired with that model. */
.acsel-open[hidden] { display:none; }
/* THE 'TEM' TOGGLE (s62, his call): a half-swatch glyph at the end of the count row — the
   coloured half on the RIGHT reads as "secondary". It's an on/off switch that flips the whole
   view (é ↔ accent); ON wears the SAME ink ring as a chosen colour swatch (it's a swatch
   relative). The number is the accent-match count (capped 99+). */
.temtog { display:inline-flex; align-items:center; gap:5px; vertical-align:-3px; margin-left:2px;
  text-decoration:none; -webkit-tap-highlight-color:transparent; }
.temtog-sw { width:16px; height:16px; border-radius:50%; border:1.5px solid var(--line-2);
  background:linear-gradient(90deg, transparent 0 50%, var(--chosen, var(--ink-faint)) 50% 100%); flex:none;
  background-clip:padding-box; }   /* s73: the half stays inside the hairline — never tiled under the border */
/* ON keeps its hairline and adds the ring OUTSIDE, exactly like the chosen colour swatch. A
   transparent border here exposed the gradient tiled under it: an orange sliver on the left
   and a bitten right edge (his "sides cropped or flipped"). */
.temtog.on .temtog-sw { box-shadow:0 0 0 2px var(--paper), 0 0 0 4px var(--ink); }
.temtog-n { font-size:12.5px; font-weight:700; color:var(--ink-faint); }
.temtog.on .temtog-n { color:var(--ink); }
.temtog:active .temtog-sw { transform:scale(.92); }
/* the same glyph as the way out of the empty é screen (nothing IS the colour, but N have it) */
.temtog-empty { justify-content:center; gap:8px; margin:2px auto 4px; padding:9px 16px;
  border:1px solid var(--line-2); border-radius:var(--r-pill); }
.temtog-emptytxt { font-size:13.5px; color:var(--ink-soft); }
.temtog-emptytxt b { color:var(--ink); }
.acsec-acts .pinclearform { margin-left:0; }
/* s62: the sell bar is a matched pair, centered — Cancelar is a real (outline) button the
   same size as Salvar, not the looks-bar's right-shoved text link. */
.selbar { justify-content:center; gap:12px; }
.selbar > span { display:none; }   /* the hidden on/off id carriers submit fine but must not eat flex gap */
.selbar .bookbar-cancel { margin-left:0; border:1px solid var(--line-2); border-radius:11px;
  padding:11px 18px; background:var(--card); color:var(--ink-soft); font-weight:600; min-width:132px; }
.selbar .bookbar-go { min-width:132px; border:1px solid transparent; }   /* 1px border → same 41px height as Cancelar */
body.selecting .tomesa, body.selecting .hold-ring { display:none; }
/* s49 — validation without native bubbles (iOS standalone strands them): the field says it */
.is-invalid, input.is-invalid, textarea.is-invalid, select.is-invalid { border-color:var(--red) !important;
  box-shadow:0 0 0 2px color-mix(in srgb, var(--red) 18%, transparent); }
.conflict-box.datehint { margin-top:8px; padding:9px 12px; font-size:12.5px; }
/* a required CHECKBOX can't wear a red border — it wears a ring, and the terms label at the
   door says the one thing left to do (the native bubble used to say it; s49 launch sweep) */
input[type="checkbox"].is-invalid { outline:2px solid var(--red); outline-offset:2px; box-shadow:none; }
.onboard-termscheck:has(.is-invalid)::after { content:"marque pra continuar"; display:block; margin-top:6px; font-size:12.5px; color:var(--red); }
/* s49 — the resolved-feedback thank-you card: one quiet line under the masthead, 'fechar' retires it */
.fbnotice { margin:10px 18px 0; padding:11px 14px; border-radius:12px; background:var(--chip-ok-bg); color:var(--chip-ok-ink);
  display:flex; align-items:flex-start; gap:12px; font-size:13.5px; line-height:1.45; }
.fbnotice q { quotes:"“" "”"; font-style:italic; }
.fbnotice form { margin:0; flex:none; }
.fbnotice-x { border:0; background:none; padding:0; font-family:inherit; font-size:12.5px; font-weight:600; color:var(--chip-ok-ink);
  text-decoration:underline; text-underline-offset:3px; cursor:pointer; }
.fbsheet-note { margin:-4px 0 12px; font-size:12.5px; color:var(--ink-faint); }
/* s51 — the recarga-recebida card: the green 'ok' notice idiom (a card you close, same as
   the feedback notice), with the pink glint (--dot, the credit-chip motif) for créditos;
   no emoji per voz §21 */
.rcnotice { margin:10px 18px 0; padding:11px 14px; border-radius:12px; background:var(--chip-ok-bg); color:var(--chip-ok-ink);
  display:flex; align-items:center; gap:10px; }
.rcnotice-body { flex:1; font-size:14px; line-height:1.35; }
.rcnotice form { margin:0; flex:none; }
.rcnotice-x { border:0; background:none; padding:0; font-family:inherit; font-size:12.5px; font-weight:600;
  color:var(--chip-ok-ink); cursor:pointer; }
.rcglint { position:relative; display:inline-block; width:16px; height:12px; vertical-align:-1px; margin-left:2px; }
.rcglint svg { position:absolute; fill:var(--dot); }
.rcglint-a { width:11px; height:11px; top:-1px; left:0; }
.rcglint-b { width:6px; height:6px; top:6px; left:9px; opacity:.85; }
.redeswitch.redehold { opacity:.85; }
.aiu-period { margin:2px 0 8px; font-size:12.5px; color:var(--ink-soft); }
.aiu-period a { color:var(--accent); text-decoration:underline; text-underline-offset:3px; }
/* s49 — the liquidação pair rides ONE card, the 'Backup e dados' dress (they floated on the
   paper). .setpair — NOT .setgroup, which is the section eyebrow's class. */
.setpair { border:1px solid var(--line); border-radius:var(--r-ctl); background:var(--card); overflow:hidden; margin-top:10px; }
/* the pair's rows are <button>s: iOS Safari ignores flex centering on a button and pads the
   top (his phone: 'excess headroom'), so the button is a plain block with no UA dress and the
   inner span lays itself out — same 13px top and bottom as the Backup row. */
.setpair .setrow { border:0; border-radius:0; display:block; -webkit-appearance:none; appearance:none;
  margin:0; padding:13px 16px; line-height:1.35; min-height:0; }
.setpair .setrow > span { display:block; }
.setpair .setrow + .setrow { border-top:1px solid var(--line); }
/* base (s49): the nota block is a SECTION — the drawer's plum head, static (no chevron),
   with a bordered body hanging from it, the 'Uso de créditos' lid+body idiom; inside, the
   drawer's own rhythm (.fiscal[open] > * + *) restated, since this box never 'opens'. */
.fiscal-inline { margin:12px 0 28px; padding:0; }   /* 16px form gap + 12 above = 28, and 28 below: one rhythm */
.fiscal-inline .fiscal-head { background:var(--grad); border:none; color:#FBF7F0; border-radius:var(--r-ctl) var(--r-ctl) 0 0; cursor:default; }
.fiscal-inline .fiscal-head b { color:#FBF7F0; font-size:12.5px; font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
.fiscal-inline .fiscal-body { border:1px solid var(--line-2); border-top:0; border-radius:0 0 var(--r-ctl) var(--r-ctl); background:var(--paper); padding:14px 16px 16px; }
/* the body is PAPER, like the page, so the fields inside read the same lighter cream as every
   other field on Perfil (on a card-toned body the field colour blended in — his phone) */
.fiscal-inline .fiscal-body input, .fiscal-inline .fiscal-body textarea, .fiscal-inline .fiscal-body select { background:var(--field); }
.fiscal-inline .fiscal-body > * + * { margin-top:20px; }
.fiscal-inline .fiscal-note { margin:0; }
.fiscal-inline .imblock { margin-top:18px; }
.fiscal-inline .imblock .hint { margin-top:8px; }
/* the Preços drawer keeps the same 28px above it as every section (it sat 10px under Apelido) */
.fiscal.catprices { margin-top:26px; }
/* THE PRICE TAG (s49, his glyph): one literal filled tag, everywhere venda is marked */
.tagglyph { fill:currentColor; stroke:none; }
.acsel-open .tagglyph { width:13px; height:13px; fill:var(--ok); stroke:none; }   /* green tag, ringed by green */
.menuact .tagglyph { fill:var(--ink-soft); stroke:none; }
/* the search pointer squeezed (s49, his B): 'N SUAS · M NA REDE ↓', nothing wraps, the venda
   door sleeps while searching, and the line never breaks at 375pt */
.acsec-pecas.acsec-pointer { overflow:visible; }   /* the pin's ✕ superscript lives above the box (v1099); wrapping is allowed (s50) */
.acsec-pecas .redejump, .acsec-pecas .mesasec-seg { white-space:nowrap; }
.acsel-open { white-space:nowrap; }
/* the intro cards draw the FAB's own glyph inline (s49) */
.pageintro-list .introglyph { width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; vertical-align:-3px; margin:0 1px; }
.setnote { margin:-6px 0 10px; font-size:12px; color:var(--ink-faint); line-height:1.4; }
.hint.warn { color:var(--warn); }

/* Tipo did-you-mean nudge (s72): suggest-only spelling help on the ficha Tipo field. */
.tiponudge{display:inline-block;margin-top:4px;padding:0;border:0;background:none;
  font-size:12px;line-height:1.4;color:var(--accent);cursor:pointer;text-decoration:underline;}

/* Collection facet + pricing door (s72, S/N pass) — 'sem preço' as a filterable stat in the
   eyebrow, and the per-category pricing tool as a small in-context text link (replaces the old
   nudge-pill band). */
.semfacet { color:inherit; text-decoration:none; display:inline-flex; align-items:center; gap:6px;
  -webkit-tap-highlight-color:transparent; }
.semfacet .mesasec-n { color:var(--accent); }
.semfacet.on { color:var(--accent); }
.semfacet:active { color:var(--accent); }
.semfacet-x { font-size:13px; line-height:1; letter-spacing:0; }
.pricedoor { display:inline-flex; align-items:center; gap:5px; margin:4px 2px 16px;
  color:var(--accent); font-family:var(--sans); font-size:12.5px; font-weight:600;
  text-decoration:none; -webkit-tap-highlight-color:transparent; }
.pricedoor-chev { width:12px; height:12px; fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; }
.pricedoor:active { color:var(--accent-press); }

/* à-venda select bar (s72): a green instruction/count line above the Cancelar·Salvar row, so
   the select mode says what to do (it was silent — just two buttons). Scoped to .selbar. */
.selbar { flex-direction:column; align-items:stretch; gap:8px; }
.selbar-hint { margin:0; font-size:13px; font-weight:600; color:var(--ok); text-align:center; }
.selbar-row { display:flex; align-items:center; gap:12px; }

/* Polir note mic (s72): the correction go-button + mic sit in the standard action row (mirrors
   the render viewer). Reset .revrefine's full-width/top-margin so it grows beside the disc. */
.searchactions-row #polishGo { width:auto; flex:1; margin:0; }

/* Render pop thumbnail + on-ficha "gerando…" label (s72). The ready pop leads with the finished
   image's own thumbnail (the grid's cover thumb, portrait — no fresh crop); with a thumb the check
   icon steps aside (it's display:grid, so hide by rule, not [hidden]). The ficha label makes the
   spinning ✦ legible as "underway" — the in-context signal that keeps the global bar off this piece. */
.renderbar-thumb { flex:none; width:30px; height:40px; border-radius:7px; object-fit:cover;
  background:var(--paper-2); }
.renderbar-thumb[hidden] { display:none; }
.renderbar.has-thumb .renderbar-ic { display:none; }

/* s72 polish-sheet + à-venda bar polish (his phone review):
   - the polir sheet gives the créditos line and Cancelar real air below Refazer com IA
   - the à-venda bar's Cancelar·Salvar sit CENTERED, not shoved left */
#polishsheet .gencost { margin-top:14px; }
#polishsheet .menusheet-cancel { margin-top:12px; }
.selbar-row { justify-content:center; }
.selbar-row .bookbar-cancel { margin-left:0; }

/* s75 "polished to leave home" — the consent popup (a raw piece tapped toward the mesa/look).
   Bottom sheet: informs + offers "Polir a peça" (an outlined door — a navigation, not a spend,
   per the plum=consequential rule) + a quiet "Agora não" that just closes. */
.polishgate { position:fixed; inset:0; z-index:130; display:flex; align-items:flex-end; justify-content:center; }
/* CRITICAL: an author `display:flex` OVERRIDES the `hidden` attribute's UA display:none, so
   without this the popup shows on EVERY page load, not just on a refused tap (the recurring
   display-overrides-hidden trap — see .provacap / .renderacts). Verify with computed display. */
.polishgate[hidden] { display:none; }
.polishgate-backdrop { position:absolute; inset:0; background:color-mix(in srgb, var(--ink) 45%, transparent); }
.polishgate-sheet { position:relative; width:100%; max-width:420px; background:var(--paper);
  border-radius:18px 18px 0 0; padding:22px 20px calc(18px + env(safe-area-inset-bottom));
  box-shadow:0 -6px 24px var(--shadow); text-align:center; }
.polishgate-msg { font-size:13.5px; line-height:1.4; color:var(--ink); margin:2px 4px 16px; }
.polishgate-go { display:block; text-decoration:none; text-align:center; background:var(--paper);
  color:var(--accent); border:1px solid var(--accent); border-radius:12px; padding:12px;
  font-weight:600; font-size:15px; }
.polishgate-go:active { background:color-mix(in srgb, var(--accent) 8%, var(--paper)); }
.polishgate-cancel { display:block; width:100%; margin-top:10px; background:none; border:none;
  color:var(--ink-faint); font-size:14px; padding:8px; cursor:pointer; }

/* s82 (his call): ONE no-photo face everywhere — FLAT plum with a soft gradient (no sphere
   highlight) + the cream initial, same as the vitrine/loja .vphoto. Masthead avatar, Perfil,
   rede cards, invite rows, maker card (a circle too). Cream in BOTH themes (the disc is always
   plum; dark mode's --on-accent is dark). A real photo still covers it via <img>. */
.avatar.nophoto, .pfavatar.nophoto, .shopav.nophoto, .invav.nophoto, .mkav.nophoto {
  background:linear-gradient(150deg,#705285 0%,#4D375F 100%); color:#FBF7F0; }
/* Rede list (his call): a photoless acervo stays SMALLER than a photo (56 vs 72 — full size is
   earned by a real photo, so empty discs don't dominate) and ALWAYS wears the ring (what used to
   mark only the circle band). */
.shopav.nophoto { --av-disc:56px; width:var(--av-disc); height:var(--av-disc); font-size:22px;
  margin-inline:calc((var(--av-col) - var(--av-disc)) / 2);
  box-shadow:none; outline:1.5px solid var(--accent); outline-offset:2px; }   /* outline: the gap shows the card's OWN ground (the me-card is greyer than --card) */

/* THE PROVA DIFF (s83, his call): in the Gerar-imagem panel, what changed in the Peças since the
   prova on screen — small 2:3 faces, a plum + on what came in, a grey − on what left (dimmed). */
.provadiff { margin:10px 0 3px; }
.provadiff[hidden] { display:none; }
.provadiff-lbl { display:block; font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 0 13px; }   /* room for the +/− badges that ride 5px above the faces */
.provadiff-row { display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.pdt { position:relative; width:44px; aspect-ratio:2/3; border-radius:8px; flex:none; }
.pdt img, .pdt .pdt-none { width:100%; height:100%; object-fit:cover; border-radius:8px; display:block; background:var(--paper-2); }
.pdt .pdt-none { display:grid; place-items:center; }
.pdt .pdt-none svg { width:60%; height:60%; stroke:var(--ink-faint); stroke-width:1.3; fill:none; opacity:.6; }
/* removed: full colour, a light fade — the grey − badge carries 'saiu'; greyscale at 44px hid the piece (his call) */
.pdt.out img, .pdt.out .pdt-none { opacity:.7; }
.pdt b { position:absolute; right:-5px; top:-5px; width:17px; height:17px; border-radius:50%; display:grid; place-items:center;
  font-size:13px; font-weight:700; line-height:1; box-shadow:0 0 0 2px var(--paper); }
.pdt.in b { background:var(--accent); color:#FBF7F0; }
.pdt.out b { background:var(--line-2); color:var(--ink); }
.pdt-more { font-size:12.5px; font-weight:600; color:var(--ink-soft); }
.provadiff-same { font-size:13px; color:var(--ink-soft); margin:0; }

/* THE LOOK DROPDOWNS AS SIBLINGS (s83, his call): 'Ajustar prova' and 'Em quem?' wear the same
   hairline frame and close by the same corner ✕ (the bottom Cancelars are gone). The ✕ glyph is
   small but its hit area is 44px; it rides the first line of each panel. */
#lookProvarPanel, #provarPanel { position:relative; padding:14px 14px 16px; background:var(--card);
  border:1px solid var(--line); border-radius:14px; }
#lookProvarPanel[hidden], #provarPanel[hidden] { display:none; }
#lookArrumar { position:relative; }
/* top/right 0: the 16px glyph's centre lands on the title's centre line and its right edge on
   the panel's content edge (1px border + 14px padding) — measured, not eyeballed */
.panelx { position:absolute; top:0; right:0; width:44px; height:44px; padding:0; border:none;
  background:none; display:grid; place-items:center; color:var(--ink-faint); cursor:pointer;
  -webkit-tap-highlight-color:transparent; z-index:2; }
.panelx svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.9; stroke-linecap:round; }
.panelx:active { color:var(--ink); }
/* 'O que refazer?' in the 'Em quem?' voice (13px semibold ink) with the same 12px under it */
#lookArrumar .lb-chips-q { font-size:13px; font-weight:600; letter-spacing:-.01em; color:var(--ink); margin-bottom:12px; }
/* when there's no 'o que refazer' choice, the field is the first line — clear the corner ✕ */
#lookArrumar #laChips[hidden] ~ .personwrap { margin-top:30px; }
