/* wireframe.css · a monochrome base kit for prototypes · v2.1 (19/10/2026) · MIT license
   The full manual is in index.html (English) and index.pt.html (Portuguese). Summary:
   · 4 colors per mode: pure white background (pure black in dark mode), ink, ONE text gray, ONE line gray.
   · SHAPE does the talking, never a new tone:
       state      error = solid block · warning = outline · info = dashed · ok = text with ✓ only
       selected   hatching · hover = ink bar at the start of the row
       category   filled square · hollow square · circle · diamond
       hierarchy  size and weight, never a lighter gray
   · Corners always square. The only circle is the category one (.shape.ring, .wf-mk.k-ring).
   · No block shadow. Box-shadow only exists as an inner stroke (3px bar).
   · Every size comes from a token: space (--sp-*), stroke (--s-*), text (--t-*), height (--h-*).
     Run tools/lint-css.mjs on the app's styles.css: it flags every value off the scale.
   · Logical properties (inline-start/end) everywhere: with dir="rtl" the layout mirrors itself.
   Each app copies this file and wireframe.js and writes only its own layout in a styles.css.
   Do not edit the app's copy: change it here, bump the version and copy it again.
   Light/dark: include wireframe.js and put data-wf-theme-toggle on a button. */

:root {
  /* color: these are the only ones */
  --paper: #ffffff; --ink: #000000; --mute: #6b6b6b; --line: #d6d6d6; --hatch: rgba(0,0,0,.09);
  --panel: var(--paper);

  /* space: base 4 */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;

  /* stroke: 1 = line and control · 2 = block frame · 3 = bar (hover, focus, highlight) */
  --s-1: 1px; --s-2: 2px; --s-3: 3px;
  --s-glyph: 1.5px; /* only for drawings under 16px (the checkbox box) */

  /* text */
  --sans: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', 'Nirmala UI', 'Noto Sans', sans-serif; /* system fonts cover Arabic, Devanagari, Bengali, CJK */
  --mono: 'IBM Plex Mono', ui-monospace, Menlo, Consolas, monospace;
  --t-micro: 10px;   /* mono, capitals: tag, badge, field label, table header */
  --t-caption: 11px; /* mono: eyebrow, caption, code, source of a figure */
  --t-small: 13px;   /* supporting text, button, chip */
  --t-ui: 14px;      /* control, table cell, dense list */
  --t-body: 15px;    /* running text */
  --t-lede: 17px;    /* opening paragraph */
  --t-h3: 18px; --t-h2: 24px;
  --t-stat: 28px;    /* highlighted number in a block */
  --t-display: 44px; /* the total, the number the page exists to show */
  --t-h1: clamp(32px, 4.4vw, 52px);
  --lh-body: 1.5; --lh-tight: 1.15; --lh-display: 1.02;
  --track-caps: .12em; --track-tight: -.02em; --track-display: -.035em;

  /* control height: a button, field and select on the same row share the same height */
  --h-xs: 24px;  /* .x, .vote: the minimum touch target (WCAG 2.5.8) */
  --h-sm: 28px;  /* compact: inside tables and cells */
  --h-md: 36px;  /* default: .btn, .input, fields */
  --h-lg: 44px;  /* main action, touch on mobile */

  /* shape */
  --shape: 14px;  /* category marker, legend */
  --bar-x: var(--s-3); /* hover bar, turns negative in RTL */

  /* motion */
  --dur-1: 120ms; --dur-2: 200ms; --dur-3: 350ms; --ease: cubic-bezier(.2,.8,.2,1);

  /* layers */
  --z-pop: 20; --z-map: 500; --z-sticky: 600; --z-toast: 1000; --z-screen: 2000;

  /* measures */
  --w-frame: 1240px; --w-side: 340px; --w-measure: 62ch;

  /* aliases for v1 apps */
  --ink-2: var(--ink); --line-2: var(--line);
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --paper: #000000; --ink: #ffffff; --mute: #8f8f8f; --line: #333333; --hatch: rgba(255,255,255,.12);
} }
:root[data-theme="dark"] { --paper: #000000; --ink: #ffffff; --mute: #8f8f8f; --line: #333333; --hatch: rgba(255,255,255,.12); }
[dir="rtl"] { --bar-x: calc(-1 * var(--s-3)); }
/* letter spacing pulls apart scripts whose letters join or that have no capitals: Arabic, Urdu, Devanagari, Bengali, Chinese, Japanese */
:root:is(:lang(ar), :lang(ur), :lang(hi), :lang(bn), :lang(zh), :lang(ja)) { --track-caps: 0; --track-tight: 0; --track-display: 0; }
/* monospace fonts draw Arabic letters unjoined and have no Devanagari or Bengali: those labels use the sans */
:root:is(:lang(ar), :lang(ur), :lang(hi), :lang(bn)) { --mono: var(--sans); }

/* base */
* { box-sizing: border-box; }
*, *::before, *::after { border-radius: 0; }
.leaflet-tooltip, .leaflet-popup-content-wrapper, .leaflet-popup-tip, .leaflet-control-layers, .leaflet-bar a { border-radius: 0 !important; }
html { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; } :root[data-theme="dark"] { color-scheme: dark; }
body { margin: 0; color: var(--ink); background: var(--paper); font: var(--t-body)/var(--lh-body) var(--sans); }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--ink); text-underline-offset: 3px; }
p { margin: 0 0 var(--sp-3); }
:focus-visible { outline: var(--s-2) solid var(--ink); outline-offset: var(--s-2); }
[hidden] { display: none !important; }
.muted { color: var(--mute); }
.small { font-size: var(--t-small); }
.empty { color: var(--mute); font: var(--t-caption) var(--mono); }
.num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mono { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
/* code reads left to right in every language */
pre, code, kbd, .ltr { direction: ltr; unicode-bidi: isolate; }
pre { text-align: left; } /* lint-ok: code is always LTR, even inside an RTL page */

/* scrollbar: a square ink thumb on a line-colored track, no arrows.
   Chrome 121+ IGNORES ::-webkit-scrollbar when scrollbar-width/-color exist and draws the system
   scrollbar (rounded on Windows 11): the standard properties only go to browsers without the other one. */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--paper); box-shadow: inset var(--s-1) 0 0 var(--line); }
::-webkit-scrollbar-track:horizontal { box-shadow: inset 0 var(--s-1) 0 var(--line); }
::-webkit-scrollbar-thumb { background: var(--ink); border: 0; min-height: 40px; }
::-webkit-scrollbar-thumb:hover { background: var(--mute); }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
::-webkit-scrollbar-corner { background: var(--paper); }
@supports not selector(::-webkit-scrollbar) { * { scrollbar-width: thin; scrollbar-color: var(--ink) var(--paper); } }

/* type */
.eyebrow { display: block; font: 500 var(--t-caption) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); margin: 0 0 var(--sp-2); }
h1 { font: 800 var(--t-h1)/var(--lh-display) var(--sans); letter-spacing: var(--track-display); margin: 0 0 var(--sp-3); text-wrap: balance; }
h2 { font: 800 var(--t-h2)/var(--lh-tight) var(--sans); letter-spacing: var(--track-tight); margin: 0; text-wrap: balance; }
h3 { font: 700 var(--t-h3)/var(--lh-tight) var(--sans); letter-spacing: var(--track-tight); margin: 0 0 var(--sp-3); }
h4 { font: 700 var(--t-body)/var(--lh-tight) var(--sans); margin: 0 0 var(--sp-2); }
h3[data-level="erro"]::before { content: '✕ '; }
h3[data-level="aviso"]::before { content: '! '; }
h3[data-level="ok"]::before { content: '✓ '; }
.lede { font-size: var(--t-lede); max-width: 50ch; margin: 0 0 var(--sp-5); }
.stat { font: 800 var(--t-stat)/var(--lh-tight) var(--sans); letter-spacing: var(--track-tight); font-variant-numeric: tabular-nums; }
.display { font: 800 var(--t-display)/1 var(--sans); letter-spacing: var(--track-display); font-variant-numeric: tabular-nums; }
/* a section title with its rule: <h3 class="wf-title">Weather</h3> */
.wf-title { border-bottom: var(--s-2) solid var(--ink); padding-bottom: var(--sp-2); margin: 0 0 var(--sp-3); }

/* buttons: default = outline · .solid = the main action (one per area) · .ghost = secondary */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); min-height: var(--h-md);
  border: var(--s-1) solid var(--ink); background: var(--paper); padding: 0 var(--sp-3); cursor: pointer;
  font: 500 var(--t-small) var(--mono); transition: transform var(--dur-1), background var(--dur-1), color var(--dur-1); white-space: nowrap; }
.btn:hover { background: var(--ink); color: var(--paper); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
:is(input, select, textarea):disabled { opacity: .55; cursor: not-allowed; }
.btn.solid { background: var(--ink); color: var(--paper); }
.btn.solid:hover { background: var(--paper); color: var(--ink); }
.btn.ghost { border-color: var(--line); color: var(--mute); }
.btn.ghost:hover { border-color: var(--ink); background: var(--paper); color: var(--ink); }
.btn.sm { min-height: var(--h-sm); padding: 0 var(--sp-2); }
.btn.wide { width: 100%; min-height: var(--h-lg); white-space: normal; }
.x { display: inline-grid; place-items: center; border: var(--s-1) solid var(--line); background: transparent; width: var(--h-xs); height: var(--h-xs); padding: 0; line-height: 1; cursor: pointer; color: var(--mute); flex: none; }
.x:hover:not(:disabled) { border-color: var(--ink); color: var(--ink); }
.x:disabled { opacity: .35; cursor: default; }
.link { border: 0; background: none; padding: 0; font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; text-align: start; }

/* select: square, with the arrow drawn in ink (the native one and the rounding go away) */
select { appearance: none; -webkit-appearance: none; cursor: pointer; padding-inline-end: var(--sp-6);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }
[dir="rtl"] select { background-position: 10px 52%, 15px 52%; }
select option { background: var(--paper); color: var(--ink); }
/* date and time fields: the kit draws its own square calendar in ink (a mask painted with currentColor),
   so the icon follows the theme. The native one was invisible in dark mode. */
input::-webkit-calendar-picker-indicator { cursor: pointer; opacity: 1; width: 14px; height: 14px; padding: 0; margin-inline-start: var(--sp-1);
  background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 3h14v12H1zM1 6.5h14M4.5 1v3.5M11.5 1v3.5' fill='none' stroke='%23000' stroke-width='1.6'/%3E%3Crect x='3.5' y='9' width='3' height='3'/%3E%3C/svg%3E") center / 14px 14px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 3h14v12H1zM1 6.5h14M4.5 1v3.5M11.5 1v3.5' fill='none' stroke='%23000' stroke-width='1.6'/%3E%3Crect x='3.5' y='9' width='3' height='3'/%3E%3C/svg%3E") center / 14px 14px no-repeat; }
input::-webkit-calendar-picker-indicator:hover { background: var(--mute); }
/* checkbox: empty square when off. When on, only the ✓, no box */
input[type="checkbox"] { appearance: none; -webkit-appearance: none; width: 15px; height: 15px; margin: 0; flex: none; cursor: pointer;
  border: var(--s-glyph) solid currentColor; background: transparent; display: inline-grid; place-items: center; vertical-align: -2px; }
input[type="checkbox"]::before { content: '✓'; font: 800 var(--t-body)/1 var(--sans); transform: translateY(-1px) scale(.4); opacity: 0; transition: transform var(--dur-1), opacity var(--dur-1); }
input[type="checkbox"]:checked { border-color: transparent; }
input[type="checkbox"]:checked::before { opacity: 1; transform: translateY(-1px) scale(1); }
input[type="checkbox"]:focus-visible { outline: var(--s-2) solid currentColor; outline-offset: var(--s-2); }

/* fields. Labelled: <label class="field">Name<input></label> · standalone: <input class="input"> */
.field { display: flex; flex-direction: column; gap: var(--sp-1); font: 500 var(--t-micro) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); min-width: 0; }
.field input, .field select, .field textarea, .input { min-height: var(--h-md); border: var(--s-1) solid var(--ink); background-color: var(--paper); padding: 0 var(--sp-3); min-width: 0;
  font: 500 var(--t-ui) var(--sans); text-transform: none; letter-spacing: 0; color: var(--ink); }
.field select, select.input { padding-inline-end: var(--sp-6); }
.field textarea, textarea.input { padding: var(--sp-2) var(--sp-3); min-height: calc(var(--h-md) * 2); resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus, .input:focus { outline: none; box-shadow: inset 0 calc(-1 * var(--s-3)) 0 var(--ink); }
.field .hint { font: 400 var(--t-caption) var(--sans); text-transform: none; letter-spacing: 0; }
/* editing inside a table cell. A select grows with its text: it never cuts its own label */
.cell { min-height: var(--h-sm); border: var(--s-1) solid transparent; background-color: transparent; padding: 0 var(--sp-2); font-size: var(--t-ui); min-width: 0; }
input.cell { width: 100%; }
select.cell { width: auto; max-width: 100%; padding-inline-end: var(--sp-5); background-position: calc(100% - 11px) 52%, calc(100% - 6px) 52%; }
[dir="rtl"] select.cell { background-position: 6px 52%, 11px 52%; }
.cell:hover { border-color: var(--line); } .cell:focus { outline: none; border-color: var(--ink); }

/* surfaces: 2px frame on the top-level block, 1px on what lives inside it */
.card { background: var(--paper); border: var(--s-2) solid var(--ink); padding: var(--sp-4); }
.card.sub { border-width: var(--s-1); padding: var(--sp-3); }
.card.dashed { border-style: dashed; }
.card.strong { box-shadow: inset var(--bar-x) 0 0 var(--ink); }
.divider { border: 0; border-top: var(--s-1) dashed var(--line); margin: var(--sp-3) 0; }
/* a note in the margin: <p class="wf-note">…</p> */
.wf-note { border-inline-start: var(--s-3) solid var(--ink); padding-inline-start: var(--sp-3); margin: 0 0 var(--sp-3); }
/* a collapsed extra: <details class="wf-more"><summary>See the table</summary>…</details> */
.wf-more > summary { cursor: pointer; font: 600 var(--t-caption) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); padding: var(--sp-1) 0; }
.wf-more[open] > summary { margin-bottom: var(--sp-2); }

/* labels */
.tag { display: inline-block; font: 600 var(--t-micro)/1.4 var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); border: var(--s-1) solid var(--line); padding: 1px var(--sp-1); text-align: center; color: var(--mute); white-space: nowrap; vertical-align: 1px; }
.tag[data-level="erro"], .tag.solid { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.tag[data-level="aviso"], .tag.outline { border-color: var(--ink); color: var(--ink); }
.tag[data-level="info"], .tag.dashed { border: var(--s-1) dashed var(--ink); color: var(--ink); }
.tag[data-level="ok"], .tag.done { border-color: transparent; color: var(--ink); padding-inline-start: 0; }
.tag[data-level="ok"]::before, .tag.done::before { content: '✓ '; }
.badge { display: inline-block; font: 600 var(--t-micro)/1.4 var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); border: var(--s-1) solid var(--ink); padding: 1px var(--sp-1); white-space: nowrap; }
/* a button with a count (votes, likes): pressed = filled */
.vote { min-height: var(--h-xs); border: var(--s-1) solid var(--ink); background: transparent; font: 600 var(--t-caption) var(--mono); padding: 0 var(--sp-2); cursor: pointer; }
.vote.on, .vote[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
/* a suggestion to add: dashed until the mouse arrives */
.chip { min-height: var(--h-sm); border: var(--s-1) dashed var(--ink); background: var(--paper); padding: 0 var(--sp-3); cursor: pointer; font-size: var(--t-small); }
.chip:hover { border-style: solid; }
/* a pill-shaped checkbox: checked = filled */
.tick { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--h-sm); font-size: var(--t-small); cursor: pointer; border: var(--s-1) solid var(--ink); padding: 0 var(--sp-2); }
.tick input { color: inherit; }
.tick:has(input:checked) { background: var(--ink); color: var(--paper); }
.tick.sm { min-height: var(--h-xs); padding: 0 var(--sp-1); gap: var(--sp-1); font: 600 var(--t-caption) var(--mono); }

/* numbers in a block: <div class="wf-stats"><div class="wf-stat"><span class="eyebrow">Today</span><b>R$ 5,40</b><span>source</span></div></div> */
.wf-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); border: var(--s-2) solid var(--ink); }
.wf-stats:empty { display: none; }
.wf-stat { display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-3); border-inline-end: var(--s-1) solid var(--line); min-width: 0; }
.wf-stat:last-child { border-inline-end: 0; }
.wf-stat .eyebrow { margin: 0; }
.wf-stat > b { font: 800 var(--t-stat)/var(--lh-tight) var(--sans); letter-spacing: var(--track-tight); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.wf-stat > span:not(.eyebrow) { font-size: var(--t-small); }
.wf-stats.sm .wf-stat > b { font-size: var(--t-h3); }

/* image placeholder: <div class="hatch"><span class="xh"></span><span class="ann tl">photo</span></div> */
.hatch { position: relative; min-height: 160px; border: var(--s-2) solid var(--ink);
  background: repeating-linear-gradient(-45deg, var(--hatch) 0 1px, transparent 1px 9px), var(--paper); }
.xh::before, .xh::after { content: ''; position: absolute; background: var(--line); }
.xh::before { inset-inline-start: 50%; top: 0; bottom: 0; width: var(--s-1); }
.xh::after { top: 50%; inset-inline: 0; height: var(--s-1); }
.ann { position: absolute; font: var(--t-caption) var(--mono); background: var(--paper); border: var(--s-1) solid var(--ink); padding: var(--sp-1) var(--sp-2); }
.ann.tl { top: var(--sp-3); inset-inline-start: var(--sp-3); text-transform: uppercase; letter-spacing: var(--track-caps); }
.ann.tr { top: var(--sp-3); inset-inline-end: var(--sp-3); } .ann.bl { bottom: var(--sp-3); inset-inline-start: var(--sp-3); } .ann.br { bottom: var(--sp-3); inset-inline-end: var(--sp-3); }

/* progress bar: <div class="meter"><span style="width:40%"></span></div>. Span.over = over the limit */
.meter { height: var(--sp-2); border: var(--s-1) solid var(--ink); background: repeating-linear-gradient(90deg, transparent 0 9px, var(--line) 9px 10px); }
.meter span { display: block; height: 100%; background: var(--ink); transition: width var(--dur-3) var(--ease); }
.meter span.over { background: repeating-linear-gradient(-45deg, var(--ink) 0 3px, transparent 3px 6px); }

/* tables */
table { width: 100%; border-collapse: collapse; background: var(--paper); }
th { font: 500 var(--t-micro) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); text-align: start;
  padding: var(--sp-2) var(--sp-3); border-bottom: var(--s-1) solid var(--ink); position: sticky; top: 0; background: var(--paper); white-space: nowrap; }
td { padding: var(--sp-3); border-bottom: var(--s-1) solid var(--line); vertical-align: middle; font-size: var(--t-ui); }
td small { display: block; font: var(--t-caption) var(--mono); color: var(--mute); margin-top: 2px; }
table.dense td { padding: var(--sp-1) var(--sp-2); }
tr:hover td:first-child, .wf-hover:hover { box-shadow: inset var(--bar-x) 0 0 var(--ink); }
table.dense tr:hover td:first-child, .sheet tr.cat:hover td:first-child { box-shadow: none; }
tr.chosen td { background: repeating-linear-gradient(-45deg, var(--hatch) 0 1px, transparent 1px 7px); }
tr.off td { opacity: .45; }
/* sheet: a table framed at the top and bottom. Tr.cat = group row */
.sheet { border-top: var(--s-2) solid var(--ink); border-bottom: var(--s-2) solid var(--ink); }
.sheet tr.cat td { font: 600 var(--t-caption) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); border-bottom: var(--s-1) solid var(--ink); padding-top: var(--sp-4); }
.wf-scroll { overflow-x: auto; max-width: 100%; }

/* dialog */
dialog { border: var(--s-2) solid var(--ink); padding: 0; width: min(880px, calc(100vw - var(--sp-6))); max-height: min(78vh, 720px); background: var(--paper); color: var(--ink); }
dialog[open] { display: flex; flex-direction: column; animation: wf-pop var(--dur-2) ease-out; }
dialog::backdrop { background: rgba(0,0,0,.4); backdrop-filter: grayscale(1) blur(2px); }
@keyframes wf-pop { from { transform: translateY(6px); opacity: 0; } to { transform: none; opacity: 1; } }
.wf-dhead { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); border-bottom: var(--s-2) solid var(--ink); }
.wf-dhead h3 { margin: 0; font-family: var(--mono); font-weight: 600; }
.wf-dhead .x { width: var(--h-sm); height: var(--h-sm); font-size: var(--t-h3); }

/* passing notice: a <div class="toast" role="status"></div>, with .on to show it */
.toast { position: fixed; left: 50%; /* lint-ok: centred, symmetric in RTL */ bottom: var(--sp-5); transform: translate(-50%, 20px); background: var(--ink); color: var(--paper);
  font: var(--t-small) var(--mono); padding: var(--sp-3) var(--sp-4); opacity: 0; pointer-events: none; transition: var(--dur-2); max-width: calc(100vw - var(--sp-6)); z-index: var(--z-toast); }
.toast.on { opacity: 1; transform: translate(-50%, 0); }

/* tabs: <nav class="wf-tabs"><button aria-selected="true">A <span class="count">3</span></button></nav> */
.wf-tabs { display: flex; flex-wrap: wrap; border-bottom: var(--s-2) solid var(--ink); } /* never scrolls: tabs that do not fit go to a second line */
@supports not selector(::-webkit-scrollbar) { .wf-tabs { scrollbar-width: none; } }
.wf-tabs::-webkit-scrollbar { display: none; }
.wf-tabs button { min-height: var(--h-md); border: var(--s-2) solid transparent; border-bottom: 0; background: transparent; padding: 0 var(--sp-3); cursor: pointer;
  font: 500 var(--t-caption) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); white-space: nowrap; margin-bottom: calc(-1 * var(--s-2)); }
.wf-tabs button:hover { color: var(--ink); }
.wf-tabs button[aria-selected="true"] { color: var(--ink); background: var(--paper); border-color: var(--ink); font-weight: 600; }
.wf-tabs .count { margin-inline-start: var(--sp-2); border: var(--s-1) solid currentColor; padding: 0 var(--sp-1); font-size: var(--t-micro); }
.wf-tabs .count:empty { display: none; }
/* tabs on more than one line: wireframe.js adds .is-wrapped and the strip becomes a grid of tabs.
   Nothing hides off-screen. The current tab is the inverted one */
.wf-tabs.is-wrapped { gap: var(--sp-1); padding-bottom: var(--sp-2); }
.wf-tabs.is-wrapped button { min-height: var(--h-sm); border: var(--s-1) solid var(--line); margin-bottom: 0; }
.wf-tabs.is-wrapped button:hover { border-color: var(--ink); }
.wf-tabs.is-wrapped button[aria-selected="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* legend and shapes: the same as the map markers */
.wf-legend { display: flex; align-items: center; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; font: var(--t-caption) var(--mono); color: var(--mute); }
.shape { display: inline-grid; place-items: center; width: var(--shape); height: var(--shape); border: var(--s-2) solid var(--ink); font: 600 var(--t-micro) var(--mono); color: var(--paper); flex: none; }
.shape.fill { background: var(--ink); } .shape.ring { border-radius: 50%; } .shape.dia { transform: rotate(45deg) scale(.8); }
.shape.pin { background: var(--ink); width: 16px; height: 16px; }
.shape.dashed { border-style: dashed; }
.shape.hatched { width: 22px; background: repeating-linear-gradient(-45deg, var(--hatch) 0 1px, transparent 1px 5px); border-width: var(--s-1); }

/* history: <ul class="feed"><li>…</li></ul> */
.feed { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--t-ui); }
.feed li { border-inline-start: var(--s-2) solid var(--ink); padding-inline-start: var(--sp-2); }
.feed li.empty { border: 0; padding: 0; }
/* numbered steps: <ol class="steps"><li><span class="num-dot">1</span><span>…</span><span>actions</span></li></ol> */
.steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.steps li { display: grid; grid-template-columns: var(--h-xs) minmax(0, 1fr) auto; gap: var(--sp-2); align-items: start; padding: var(--sp-2) 0; border-bottom: var(--s-1) solid var(--line); font-size: var(--t-ui); }
.steps li.empty { display: block; border: 0; }
.num-dot { width: var(--h-xs); height: var(--h-xs); background: var(--ink); color: var(--paper); display: grid; place-items: center; font: 600 var(--t-caption) var(--mono); flex: none; }
.num-dot.outline { background: var(--paper); color: var(--ink); border: var(--s-2) solid var(--ink); }
/* simple list with an action at the end: <ul class="wf-list"><li>text <button class="x">×</button></li></ul> */
.wf-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--t-ui); }
.wf-list li { display: flex; align-items: center; gap: var(--sp-2); } .wf-list li > .x:last-child { margin-inline-start: auto; }

/* maps (Leaflet): <div class="wf-map"><div id="m" style="height:400px"></div><div class="wf-map-card">…</div></div>
   Tiles with no key and already gray: Esri Canvas World_Light_Gray_Base / World_Dark_Gray_Base. */
.wf-map { position: relative; border: var(--s-2) solid var(--ink); }
.wf-map-card { position: absolute; z-index: var(--z-map); inset-inline-start: var(--sp-3); bottom: var(--sp-3); background: var(--paper); border: var(--s-2) solid var(--ink); padding: var(--sp-3); font-size: var(--t-ui); max-width: min(340px, calc(100% - var(--sp-5))); }
.leaflet-container { font-family: var(--sans); background: var(--paper); }
.leaflet-bar { border: var(--s-2) solid var(--ink) !important; border-radius: 0 !important; box-shadow: none !important; }
.leaflet-bar a, .leaflet-bar a:hover { background: var(--paper); color: var(--ink); border-color: var(--ink); border-radius: 0 !important; }
.leaflet-control-attribution { background: var(--paper) !important; color: var(--mute) !important; font: var(--t-micro) var(--mono); }
.leaflet-control-attribution a { color: var(--ink) !important; }
.leaflet-attribution-flag { display: none !important; } /* the only colour on the page: Leaflet adds it by default */
.wf-tip { background: var(--paper); color: var(--ink); border: var(--s-glyph) solid var(--ink); border-radius: 0; box-shadow: none; font: 600 var(--t-caption) var(--mono); padding: 2px var(--sp-2); }
.wf-tip::before { display: none; }
/* numbered pin (L.divIcon className 'wf-pin', html <span>1</span>) */
.wf-pin span { height: var(--h-xs); min-width: var(--h-xs); padding: 0 var(--sp-2); background: var(--ink); color: var(--paper); border: var(--s-2) solid var(--paper);
  display: grid; place-items: center; font: 600 var(--t-caption) var(--mono); box-shadow: 0 0 0 var(--s-2) var(--ink); white-space: nowrap; }
/* category marker (className 'wf-mk k-fill|k-sq|k-ring|k-dia', html <span></span>) */
.wf-mk span { display: block; width: var(--shape); height: var(--shape); border: var(--s-2) solid var(--ink); background: var(--paper); }
.wf-mk.k-fill span { background: var(--ink); }
.wf-mk.k-ring span { border-radius: 50%; }
.wf-mk.k-dia span { transform: rotate(45deg); width: 12px; height: 12px; }

/* layout */
.wf-frame { max-width: var(--w-frame); margin: 0 auto; padding: var(--sp-5) var(--sp-5) var(--sp-7); }
.wf-stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.wf-stack.lg { gap: var(--sp-5); }
.wf-row { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.wf-row.end { align-items: end; } .wf-row.lg { gap: var(--sp-3); }
.wf-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: var(--sp-4); }
.wf-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: var(--sp-3); }
.wf-split { display: grid; grid-template-columns: minmax(0, 1fr) var(--w-side); gap: var(--sp-6); align-items: start; }
.grow { flex: 1; min-width: 0; }
@media (max-width: 900px) { .wf-split { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .wf-frame { padding: var(--sp-4) var(--sp-4) var(--sp-6); } }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* number fields: no native arrows. wireframe.js adds square − / + buttons */
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.wf-num { display: inline-flex; align-items: stretch; max-width: 100%; min-width: 0; }
.field .wf-num { display: flex; min-width: 120px; } /* below this the value is cut: steppers take 56px */
.wf-num input { flex: 1 1 0; width: 0; min-width: 3ch; text-align: center; padding-inline: var(--sp-1); font-variant-numeric: tabular-nums; }
.wf-step { flex: none; width: var(--h-sm); border: var(--s-1) solid var(--ink); background: var(--paper); color: var(--ink); padding: 0; cursor: pointer; font: 600 var(--t-ui)/1 var(--mono); }
.wf-step:first-child { margin-inline-end: calc(-1 * var(--s-1)); } .wf-step:last-child { margin-inline-start: calc(-1 * var(--s-1)); }
.wf-step:hover { background: var(--ink); color: var(--paper); }
.wf-step:active { transform: translateY(1px); }
/* compact: in a table cell the buttons use the thin line, like the cell */
.wf-num:has(.cell) .wf-step { border-color: var(--line); width: var(--h-xs); font-size: var(--t-small); }
.wf-num:has(.cell):hover .wf-step, .wf-num:has(.cell):focus-within .wf-step { border-color: var(--ink); }

/* ═══ v2.1 · universal pieces (forms, navigation, states, overlays, content, charts) ═══════════════════════════════ */

/* ── form ── */
/* radio: empty square, and when checked it gets a filled square inside (a checked checkbox is only the ✓) */
input[type="radio"] { appearance: none; -webkit-appearance: none; width: 15px; height: 15px; margin: 0; flex: none; cursor: pointer; vertical-align: -2px;
  border: var(--s-glyph) solid currentColor; background: transparent; }
input[type="radio"]:checked { background: currentColor; box-shadow: inset 0 0 0 3px var(--paper); }
input[type="radio"]:focus-visible { outline: var(--s-2) solid currentColor; outline-offset: var(--s-2); }
/* on/off switch: <input type="checkbox" class="wf-switch" role="switch"> */
input[type="checkbox"].wf-switch { width: 34px; height: 20px; border: var(--s-1) solid currentColor; display: inline-flex; align-items: center; padding: 2px; vertical-align: -5px; }
input[type="checkbox"].wf-switch::before { content: ''; width: 14px; height: 14px; background: currentColor; opacity: 1; transform: none; transition: transform var(--dur-1) var(--ease); }
input[type="checkbox"].wf-switch:checked { background: currentColor; border-color: currentColor; }
input[type="checkbox"].wf-switch:checked::before { background: var(--paper); transform: translateX(14px); }
[dir="rtl"] input[type="checkbox"].wf-switch:checked::before { transform: translateX(-14px); }
/* pick one among a few: <div class="wf-seg" role="radiogroup"><label><input type="radio" name="v" checked><span>Day</span></label>…</div> */
.wf-seg { display: inline-flex; border: var(--s-1) solid var(--ink); }
.wf-seg label { display: contents; }
.wf-seg input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.wf-seg span { display: inline-flex; align-items: center; min-height: var(--h-sm); padding: 0 var(--sp-3); font: 500 var(--t-small) var(--mono); cursor: pointer; border-inline-start: var(--s-1) solid var(--ink); }
.wf-seg label:first-child span { border-inline-start: 0; }
.wf-seg input:checked + span { background: var(--ink); color: var(--paper); }
.wf-seg input:focus-visible + span { outline: var(--s-2) solid var(--ink); outline-offset: var(--s-2); }
/* slider: <input type="range"> */
/* a range inside a .field drops the text-field frame */
.field input[type="range"] { border: 0; padding: 0; min-height: var(--h-sm); box-shadow: none; background-color: transparent; }
input[type="range"] { appearance: none; -webkit-appearance: none; width: 100%; height: var(--h-sm); background: transparent; cursor: pointer; margin: 0; }
input[type="range"]::-webkit-slider-runnable-track { height: var(--s-2); background: var(--ink); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; margin-top: -7px; background: var(--ink); border: var(--s-2) solid var(--paper); box-shadow: 0 0 0 var(--s-1) var(--ink); } /* lint-ok: centres the 16px thumb on the 2px track */
input[type="range"]::-moz-range-track { height: var(--s-2); background: var(--ink); }
input[type="range"]::-moz-range-thumb { width: 12px; height: 12px; background: var(--ink); border: var(--s-2) solid var(--paper); box-shadow: 0 0 0 var(--s-1) var(--ink); }
/* search: <label class="wf-search"><input type="search" placeholder="search"><button type="button" class="x" data-wf-clear aria-label="Clear">×</button></label> */
.wf-search { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--h-md); border: var(--s-1) solid var(--ink); padding-block: 0; padding-inline: var(--sp-3) var(--sp-2); background: var(--paper); }
.wf-search::before { content: ''; width: 14px; height: 14px; flex: none; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 1.5h9v9h-9zM10 10l4.5 4.5' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E") center / 14px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 1.5h9v9h-9zM10 10l4.5 4.5' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E") center / 14px no-repeat; }
.wf-search input { flex: 1; min-width: 0; min-height: var(--h-sm); border: 0; background: transparent; padding: 0; font: 500 var(--t-ui) var(--sans); color: var(--ink); }
.wf-search input:focus { outline: none; }
.wf-search:focus-within { box-shadow: inset 0 calc(-1 * var(--s-3)) 0 var(--ink); }
.wf-search input::-webkit-search-cancel-button { display: none; }
.wf-search input:placeholder-shown + [data-wf-clear] { visibility: hidden; }
/* file: <label class="wf-drop"><input type="file" multiple><b>Drop the files here</b><span>or click</span><span data-wf-files></span></label> */
.wf-drop { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-1); min-height: 140px; padding: var(--sp-4); text-align: center;
  border: var(--s-2) dashed var(--ink); cursor: pointer; font-size: var(--t-small); }
.wf-drop input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.wf-drop.on, .wf-drop:focus-within { border-style: solid; background: repeating-linear-gradient(-45deg, var(--hatch) 0 1px, transparent 1px 7px); }
.wf-drop [data-wf-files] { font: var(--t-caption) var(--mono); color: var(--mute); }
/* field with an error: <label class="field">Email<input aria-invalid="true"><span class="field-msg">The @ is missing.</span></label> */
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"], .input[aria-invalid="true"] { border-width: var(--s-2); box-shadow: inset 0 calc(-1 * var(--s-3)) 0 var(--ink); }
.field-msg { font: 600 var(--t-small) var(--sans); text-transform: none; letter-spacing: 0; color: var(--ink); }
.field-msg::before { content: '✕ '; }
.field-msg.ok { font-weight: 400; color: var(--mute); }
.field-msg.ok::before { content: '✓ '; }
/* key: <kbd>Ctrl</kbd> */
kbd { display: inline-block; font: 500 var(--t-caption) var(--mono); border: var(--s-1) solid var(--ink); border-bottom-width: var(--s-2); padding: 0 var(--sp-1); }

/* ── navigation ── */
/* app bar: <header class="wf-topbar"><b class="wf-logo">App</b><nav>…links…</nav><div class="wf-row">…</div></header> */
.wf-topbar { display: flex; align-items: center; gap: var(--sp-2) var(--sp-5); min-height: var(--sp-8); padding: var(--sp-2) var(--sp-5); border-bottom: var(--s-2) solid var(--ink); flex-wrap: wrap; }
.wf-topbar nav { display: flex; gap: var(--sp-4); flex: 1; flex-wrap: wrap; }
.wf-topbar nav a, .wf-sidenav a { text-decoration: none; color: var(--mute); font: 500 var(--t-small) var(--mono); }
.wf-topbar nav a:hover, .wf-sidenav a:hover { color: var(--ink); }
.wf-topbar nav a[aria-current="page"] { color: var(--ink); font-weight: 600; box-shadow: inset 0 calc(-1 * var(--s-3)) 0 var(--ink); padding-bottom: var(--sp-1); }
@media (max-width: 640px) { .wf-topbar { padding: var(--sp-3) var(--sp-4); } .wf-topbar nav { order: 3; flex-basis: 100%; } }
.wf-logo { font: 700 var(--t-body) var(--mono); display: inline-flex; align-items: center; gap: var(--sp-2); }
.wf-logo::before { content: ''; width: 14px; height: 14px; background: var(--ink); }
/* app with a side menu: <div class="wf-shell"><nav class="wf-sidenav">…</nav><main>…</main></div> */
.wf-shell { display: grid; grid-template-columns: 220px minmax(0, 1fr); min-height: 100vh; }
.wf-sidenav { display: flex; flex-direction: column; gap: 2px; padding: var(--sp-4) 0; border-inline-end: var(--s-2) solid var(--ink); }
.wf-sidenav .eyebrow { padding: var(--sp-4) var(--sp-4) var(--sp-1); margin: 0; }
.wf-sidenav a { padding: var(--sp-2) var(--sp-4); white-space: nowrap; }
.wf-sidenav a[aria-current="page"] { color: var(--ink); font-weight: 600; box-shadow: inset var(--bar-x) 0 0 var(--ink); }
.wf-shell > main { padding: var(--sp-5); min-width: 0; }
@media (max-width: 760px) { .wf-shell { grid-template-columns: minmax(0, 1fr); } .wf-sidenav { flex-direction: row; overflow-x: auto; border-inline-end: 0; border-bottom: var(--s-2) solid var(--ink); padding: 0; } .wf-sidenav .eyebrow { display: none; } }
/* breadcrumbs: <ol class="wf-crumbs"><li><a href="#">Home</a></li><li aria-current="page">Here</li></ol> */
.wf-crumbs { list-style: none; margin: 0 0 var(--sp-3); padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-1); font: var(--t-caption) var(--mono); color: var(--mute); }
.wf-crumbs li + li::before { content: '/'; margin-inline-end: var(--sp-1); }
.wf-crumbs a { color: var(--mute); }
.wf-crumbs [aria-current] { color: var(--ink); }
/* pagination: <nav class="wf-pages"><button>←</button><button aria-current="page">1</button>…</nav> */
.wf-pages { display: flex; gap: var(--sp-1); flex-wrap: wrap; }
.wf-pages :is(button, a) { min-width: var(--h-sm); min-height: var(--h-sm); display: inline-grid; place-items: center; padding: 0 var(--sp-2); border: var(--s-1) solid var(--line); background: var(--paper); color: var(--ink); font: 500 var(--t-small) var(--mono); text-decoration: none; cursor: pointer; }
.wf-pages :is(button, a):hover { border-color: var(--ink); }
.wf-pages [aria-current="page"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.wf-pages .gap { border-color: transparent; cursor: default; }
/* wizard steps: <ol class="wf-wizard"><li class="done">Details</li><li aria-current="step">Payment</li><li>Done</li></ol> */
.wf-wizard { list-style: none; margin: 0; padding: 0; display: flex; counter-reset: wz; }
.wf-wizard li { counter-increment: wz; flex: 1; display: flex; flex-direction: column; gap: var(--sp-2); font: 500 var(--t-caption) var(--mono); color: var(--mute); position: relative; min-width: 0; padding-inline-end: var(--sp-2); }
.wf-wizard li::before { content: counter(wz); width: var(--h-xs); height: var(--h-xs); display: grid; place-items: center; border: var(--s-2) solid var(--line); background: var(--paper); color: var(--mute); position: relative; z-index: 1; }
.wf-wizard li:not(:last-child)::after { content: ''; position: absolute; top: 11px; inset-inline: var(--h-xs) 0; height: var(--s-2); background: var(--line); }
.wf-wizard li.done { color: var(--ink); }
.wf-wizard li.done::before { content: '✓'; border-color: var(--ink); color: var(--ink); }
.wf-wizard li.done::after { background: var(--ink); }
.wf-wizard li[aria-current="step"] { color: var(--ink); font-weight: 600; }
.wf-wizard li[aria-current="step"]::before { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* ── notices and states ── */
/* <div class="wf-callout" data-level="aviso"><b>Title</b><p>Text</p></div> (data-level values stay in Portuguese: erro = error, aviso = warning, info, ok) */
.wf-callout { display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-3) var(--sp-4); border: var(--s-1) solid var(--ink); font-size: var(--t-ui); }
.wf-callout p { margin: 0; }
.wf-callout[data-level="erro"] { background: var(--ink); color: var(--paper); }
.wf-callout[data-level="erro"] a { color: var(--paper); }
.wf-callout[data-level="aviso"] { border-width: var(--s-2); box-shadow: inset var(--bar-x) 0 0 var(--ink); }
.wf-callout[data-level="info"] { border-style: dashed; }
.wf-callout[data-level="ok"] { border-color: var(--line); }
.wf-callout[data-level="erro"] > b::before { content: '✕ '; }
.wf-callout[data-level="aviso"] > b::before { content: '! '; }
.wf-callout[data-level="ok"] > b::before { content: '✓ '; }
/* nothing yet: <div class="wf-empty"><b>No flights</b><span>Add the first flight of the trip.</span><button class="btn">+ Flight</button></div> */
.wf-empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); padding: var(--sp-6) var(--sp-4); text-align: center; border: var(--s-1) dashed var(--line); }
.wf-empty > b { font-size: var(--t-h3); }
.wf-empty > span { color: var(--mute); font-size: var(--t-small); max-width: 40ch; }
.wf-empty .btn { margin-top: var(--sp-2); }
/* loading a block: <div class="wf-skel line"></div> · loading without knowing how long: <div class="wf-busy"></div> */
.wf-skel { min-height: var(--sp-4); background: repeating-linear-gradient(-45deg, var(--hatch) 0 1px, transparent 1px 7px); background-size: 200% 100%; animation: wf-skel 1.4s linear infinite; } /* lint-ok: a loop, not a response: slower than the interaction durations */
.wf-skel.line { min-height: var(--sp-3); height: var(--sp-3); margin-bottom: var(--sp-2); }
.wf-skel.short { width: 60%; }
@keyframes wf-skel { to { background-position: -40px 0; } }
.wf-busy { height: var(--sp-2); border: var(--s-1) solid var(--ink); position: relative; overflow: hidden; }
.wf-busy::after { content: ''; position: absolute; top: 0; bottom: 0; width: 30%; background: var(--ink); animation: wf-busy 1.1s var(--ease) infinite; }
@keyframes wf-busy { from { inset-inline-start: -30%; } to { inset-inline-start: 100%; } }

/* ── overlays ── */
/* tooltip: <button data-tip="Copies the link">…</button> (shows on hover and on focus) */
[data-tip] { position: relative; }
[data-tip]:is(:hover, :focus-visible)::after { content: attr(data-tip); position: absolute; bottom: calc(100% + var(--sp-2)); inset-inline-start: 0; z-index: var(--z-pop);
  background: var(--ink); color: var(--paper); font: 500 var(--t-caption)/1.3 var(--mono); padding: var(--sp-1) var(--sp-2); white-space: nowrap; pointer-events: none; text-transform: none; letter-spacing: 0; }
/* menu: <details class="wf-menu"><summary class="btn">Actions</summary><div class="wf-menu-list"><button>Edit</button>…</div></details> */
.wf-menu { position: relative; display: inline-block; }
.wf-menu > summary { list-style: none; }
.wf-menu > summary::-webkit-details-marker { display: none; }
.wf-menu > summary::after { content: '▾'; margin-inline-start: var(--sp-1); }
.wf-menu-list { position: absolute; top: calc(100% + var(--sp-1)); inset-inline-start: 0; z-index: var(--z-pop); min-width: 200px; display: flex; flex-direction: column; background: var(--paper); border: var(--s-2) solid var(--ink); padding: var(--sp-1) 0; }
.wf-menu.end .wf-menu-list { inset-inline: auto 0; }
.wf-menu-list > :is(button, a) { text-align: start; border: 0; background: none; padding: var(--sp-2) var(--sp-3); font: 500 var(--t-ui) var(--sans); color: var(--ink); text-decoration: none; cursor: pointer; }
.wf-menu-list > :is(button, a):is(:hover, :focus-visible) { box-shadow: inset var(--bar-x) 0 0 var(--ink); outline: none; }
.wf-menu-list > hr { border: 0; border-top: var(--s-1) solid var(--line); margin: var(--sp-1) 0; }
.wf-menu-list > .danger { font-weight: 700; }
.wf-menu-list > .danger::before { content: '✕ '; }
/* drawer: <dialog class="wf-drawer" id="d">…</dialog> + <button data-wf-open="d"> and, inside, <button data-wf-close> */
dialog.wf-drawer { margin-block: 0; margin-inline: auto 0; height: 100vh; max-height: 100vh; width: min(420px, 100vw); border-width: 0; border-inline-start: var(--s-2) solid var(--ink); }
dialog.wf-drawer[open] { animation: wf-slide var(--dur-2) var(--ease); }
@keyframes wf-slide { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }
[dir="rtl"] dialog.wf-drawer[open] { animation-name: wf-slide-rtl; }
@keyframes wf-slide-rtl { from { transform: translateX(-24px); opacity: 0; } to { transform: none; opacity: 1; } }
.wf-dbody { padding: var(--sp-4); overflow: auto; display: flex; flex-direction: column; gap: var(--sp-3); }
.wf-dfoot { margin-top: auto; padding: var(--sp-3) var(--sp-4); border-top: var(--s-1) solid var(--line); display: flex; gap: var(--sp-2); justify-content: flex-end; }

/* ── content ── */
/* person: <span class="wf-avatar">FN</span> · several: <span class="wf-avatars">…</span> */
.wf-avatar { display: inline-grid; place-items: center; width: var(--sp-6); height: var(--sp-6); flex: none; border: var(--s-1) solid var(--ink); background: var(--paper); font: 600 var(--t-caption) var(--mono); text-transform: uppercase; }
.wf-avatar.solid { background: var(--ink); color: var(--paper); }
.wf-avatar.sm { width: var(--h-xs); height: var(--h-xs); font-size: var(--t-micro); }
.wf-avatars { display: inline-flex; }
.wf-avatars .wf-avatar + .wf-avatar { margin-inline-start: calc(-1 * var(--sp-1)); box-shadow: 0 0 0 var(--s-2) var(--paper); }
/* data in pairs: <dl class="wf-dl"><dt>Departure</dt><dd>15/11 · 23:10</dd>…</dl> */
.wf-dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); margin: 0; font-size: var(--t-ui); }
.wf-dl dt { font: 500 var(--t-micro) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); padding-block: var(--sp-2); padding-inline: 0 var(--sp-4); border-bottom: var(--s-1) solid var(--line); display: flex; align-items: center; }
.wf-dl dd { margin: 0; padding: var(--sp-2) 0; border-bottom: var(--s-1) solid var(--line); }
/* timeline: <ol class="wf-timeline"><li class="done"><b>Check-in</b><span>14:00</span></li>…</ol> */
.wf-timeline { list-style: none; margin: 0; padding: 0; border-inline-start: var(--s-2) solid var(--ink); }
.wf-timeline li { position: relative; padding-block: 0 var(--sp-4); padding-inline: var(--sp-4) 0; display: flex; flex-direction: column; gap: 2px; font-size: var(--t-ui); }
.wf-timeline li::before { content: ''; position: absolute; top: var(--sp-1); inset-inline-start: -7px; width: 12px; height: 12px; background: var(--paper); border: var(--s-2) solid var(--ink); }
.wf-timeline li.done::before { background: var(--ink); }
.wf-timeline li[aria-current]::before { box-shadow: inset 0 0 0 var(--s-2) var(--paper), inset 0 0 0 8px var(--ink); }
.wf-timeline li > span { color: var(--mute); font: var(--t-caption) var(--mono); }
.wf-timeline li:last-child { padding-bottom: 0; }
/* conversation: <div class="wf-chat"><span class="who">Sol</span><div class="msg">Hi</div><div class="msg me">Hello</div></div> */
.wf-chat { display: flex; flex-direction: column; gap: var(--sp-2); }
.wf-chat .msg { max-width: min(75%, 52ch); padding: var(--sp-2) var(--sp-3); border: var(--s-1) solid var(--ink); font-size: var(--t-ui); align-self: flex-start; }
.wf-chat .msg.me { align-self: flex-end; background: var(--ink); color: var(--paper); }
.wf-chat .msg small { display: block; font: var(--t-micro) var(--mono); opacity: .7; margin-top: var(--sp-1); }
.wf-chat .who { font: 500 var(--t-micro) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); margin-top: var(--sp-2); }
.wf-chat .who.me { align-self: flex-end; }
/* plans side by side: <div class="wf-plans"><article class="wf-plan best">…</article></div> */
.wf-plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: var(--sp-3); align-items: stretch; }
.wf-plan { border: var(--s-1) solid var(--ink); padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.wf-plan.best { border-width: var(--s-2); box-shadow: inset 0 var(--sp-1) 0 var(--ink); }
.wf-plan .price { font: 800 var(--t-stat)/1 var(--sans); letter-spacing: var(--track-tight); font-variant-numeric: tabular-nums; }
.wf-plan .price small { font: 400 var(--t-small) var(--sans); color: var(--mute); letter-spacing: 0; }
.wf-plan ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-1); font-size: var(--t-ui); flex: 1; }
.wf-plan li::before { content: '✓ '; font-weight: 700; }
.wf-plan li.no { color: var(--mute); }
.wf-plan li.no::before { content: '✕ '; font-weight: 400; }
/* column board: <div class="wf-board"><section><h4>To do <span>2</span></h4><div class="card sub">…</div></section>…</div> */
.wf-board { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(220px, 1fr); gap: var(--sp-3); overflow-x: auto; padding-bottom: var(--sp-2); }
.wf-board > section { display: flex; flex-direction: column; gap: var(--sp-2); border-top: var(--s-2) solid var(--ink); padding-top: var(--sp-2); min-width: 0; }
.wf-board > section > h4 { font: 600 var(--t-caption) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); margin: 0; display: flex; justify-content: space-between; }
.wf-board .card.sub { font-size: var(--t-ui); }
/* month calendar, drawn by wireframe.js: <div class="wf-cal" data-wf-cal="2026-11" data-marks="2026-11-15" data-range="2026-11-15,2026-11-22"></div> */
.wf-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: var(--s-2) solid var(--ink); max-width: 420px; }
.wf-cal .head { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; padding: var(--sp-2) 0; font-weight: 700; }
.wf-cal .head span::first-letter { text-transform: uppercase; }
.wf-cal .head button { border: var(--s-1) solid var(--line); background: var(--paper); color: var(--ink); width: var(--h-sm); height: var(--h-sm); cursor: pointer; }
.wf-cal .head button:hover { border-color: var(--ink); }
.wf-cal .wd { font: 500 var(--t-micro) var(--mono); text-transform: uppercase; letter-spacing: var(--track-caps); color: var(--mute); text-align: center; padding: var(--sp-1) 0; border-bottom: var(--s-1) solid var(--ink); }
.wf-cal button.d { aspect-ratio: 1; border: 0; border-bottom: var(--s-1) solid var(--line); background: transparent; color: var(--ink); cursor: pointer; position: relative; font: 500 var(--t-ui) var(--sans); font-variant-numeric: tabular-nums; }
.wf-cal button.d:hover { box-shadow: inset 0 0 0 var(--s-1) var(--ink); }
.wf-cal button.d.out { color: var(--mute); }
.wf-cal button.d.in { background: repeating-linear-gradient(-45deg, var(--hatch) 0 1px, transparent 1px 6px); }
.wf-cal button.d[aria-current="date"] { box-shadow: inset 0 0 0 var(--s-2) var(--ink); font-weight: 700; }
.wf-cal button.d[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.wf-cal button.d.mark::after { content: ''; position: absolute; bottom: var(--sp-1); inset-inline-start: calc(50% - 2px); width: var(--sp-1); height: var(--sp-1); background: currentColor; }

/* ── CSS-only charts ── */
/* bars: <div class="wf-bars"><div><span>Hotel</span><i style="--v:62%"></i><b>R$ 2.100</b></div>…</div> · second series: <i class="b"> */
.wf-bars { display: grid; grid-template-columns: fit-content(40%) minmax(0, 1fr) fit-content(40%); /* long labels and values wrap at 40% of the width */ gap: var(--sp-2) var(--sp-3); align-items: center; font-size: var(--t-small); }
.wf-bars > div { display: contents; }
.wf-bars > div > span { overflow-wrap: anywhere; }
.wf-bars i { display: block; height: var(--sp-3); width: var(--v, 0%); min-width: 2px; background: var(--ink); transition: width var(--dur-3) var(--ease); }
.wf-bars i.b { background: repeating-linear-gradient(-45deg, var(--ink) 0 1px, transparent 1px 4px); box-shadow: inset 0 0 0 var(--s-1) var(--ink); }
.wf-bars b { font: 600 var(--t-caption) var(--mono); font-variant-numeric: tabular-nums; text-align: end; overflow-wrap: anywhere; }
/* columns: <div class="wf-cols"><div><i style="--v:40%"></i><span>mon</span></div>…</div> */
.wf-cols { display: flex; align-items: stretch; gap: var(--sp-2); height: 180px; }
.wf-cols > div { flex: 1; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: var(--sp-1); min-width: 0; justify-items: center; }
.wf-cols > div > :first-child { align-self: end; }
.wf-cols i { display: block; width: 100%; max-width: var(--sp-7); height: var(--v, 0%); background: var(--ink); border-bottom: var(--s-1) solid var(--ink); }
.wf-cols i.b { background: repeating-linear-gradient(-45deg, var(--ink) 0 1px, transparent 1px 4px); box-shadow: inset 0 0 0 var(--s-1) var(--ink); }
.wf-cols > div > span { font: var(--t-micro) var(--mono); color: var(--mute); border-top: var(--s-1) solid var(--ink); width: 100%; text-align: center; padding-top: var(--sp-1); }
/* changing number: <span class="wf-delta up">+2,1%</span> · .down · .flat */
.wf-delta { font: 600 var(--t-caption) var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.wf-delta.up::before { content: '▲ '; }
.wf-delta.down::before { content: '▼ '; }
.wf-delta.flat::before { content: '■ '; }
