/* What a tool page needs on top of theme.css.

   This file used to hold the whole of a tool page: the bar, the brand, the
   two header controls, the footer, the panels, the dropzone, the fields and
   the grids - the same rules theme.css already carried, written out again
   and loaded after it, so on the hundred and twenty pages that link this
   file the copy here was the one that won. The keyboard hint beside Search
   was a different colour on those pages than on the rest of the site, the
   footer sat four pixels lower, and on a phone the two header controls
   never became the icon buttons the shared sheet draws.

   So the duplicates are gone. Forty-seven of them were identical to
   theme.css and were simply deleted; the ten that disagreed were the page
   chrome, and theme.css is where the page chrome lives now. What is left
   here is what a tool page has and the rest of the site does not: the
   reset, the two button shapes, and the floor a finger needs. */

/* The corners come from theme.css (--radius-sm, -md, -lg), as they do on
   every other page. They were set again here, and on the forty-five pages
   with a style block of their own, to the values theme.css had before its
   scale was settled; a sheet that restates a token is a sheet the system
   cannot change. */
* { box-sizing: border-box; margin: 0; padding: 0; }
/* The reset takes away the browser's own centring of a <dialog>: a modal
   box sat in the top-left corner until this gave the margin back. */
dialog { margin: auto; }
body {
  font-family: var(--font-sans);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.6;
  /* See app-chrome.css: 100vh on iOS is a screenful plus the URL bar, so a
     short tool page gets scroll it has no content for. */
  min-height: 100vh;
  min-height: 100dvh;
}
h1, h2, h3 {
  font-family: var(--font-headline);
  font-weight: 700;
  text-wrap: balance;
  margin: 0;
}
a { color: inherit; text-decoration: none; }

button.btn-primary {
  background: var(--accent-strong);
  color: #FFF;
  border: 1px solid var(--accent-strong);
  padding: 10px 20px;
  border-radius: 8px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
button.btn-primary:hover { opacity: 0.92; }

button.btn-secondary {
  background: var(--paper-inset);
  color: var(--ink);
  border: 1px solid var(--rule-strong);
  padding: 10px 18px;
  border-radius: 8px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0;
  cursor: pointer;
}
button.btn-secondary:hover { border-color: var(--accent); }

/* A button that cannot be pressed yet has to look it. Neither this file nor
   theme.css said anything about a disabled .btn-primary, so "Make it
   smaller" before a PDF was chosen was the same solid accent, at full
   opacity, with the same pointer, as the button that works - and the only
   way to find out was to press it and have nothing happen. Written after
   the two :hover rules so that pointing at it does not brighten it again. */
button.btn-primary:disabled, button.btn-secondary:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
/* The filled button loses its lift; the secondary keeps its hairline,
   which is its edge, or it would fade into the panel altogether. */
button.btn-primary:disabled { box-shadow: none; }
button.btn-primary:disabled::after { animation: none; }

/* A slider is drawn in the accent, like a tick box, and on its own. Left to
   the browser it was the system's bright blue on PRESS; put inside a .field,
   as on SHRINK and KEYS, it picked up the sunk box theme.css draws for a text
   box, so the track sat in a bordered well. The same slider in three looks
   on three pages; now one. The attribute selector keeps this level with the
   .field rule in theme.css, and this file loads after it. */
input[type="range"] { accent-color: var(--accent-strong); }
.field input[type="range"] {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

/* The top of a tool page: the title, the one line under it, and on most
   tool pages a longer paragraph after that saying who the tool is for and
   what it does and does not do. The paragraph was written into each page
   as a plain .sub, so it came out larger than the line above it, ran the
   full width while the line above stopped at 780px, and sat against it
   with no space between: two intros, the second one louder. It is the
   same intro in two parts, so it takes the same measure, a paragraph's
   space, and a step down in size, and the line under the title stays the
   lead. Both keep text-wrap: pretty, so a paragraph does not end on one
   word on a line of its own. */
.page-header .page-sub { text-wrap: pretty; }
.page-header .os-intro {
  max-width: 780px;
  margin: 12px 0 0;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink-soft);
  text-wrap: pretty;
}
@media (max-width: 768px) {
  .page-header .os-intro { font-size: 13.5px; margin-top: 10px; }
}

/* The floor for anything a finger touches is 44px, not 40. This block said
   40 and, because it was written as button.btn-primary rather than
   .btn-primary, it also out-specified every page that had noticed and tried
   to fix it in its own style block - so those attempts silently did nothing.
   One rule, at one specificity, for the whole suite. */
@media (pointer: coarse) {
  button.btn-primary, button.btn-secondary, .btn-primary, .btn-secondary,
  .field input:where(:not([type="checkbox"]):not([type="radio"])), .field select, .field textarea,
  .btn, button.btn { min-height: 44px; }
}

/* ---------------------------------------------------------------------------
   The shared kit for the Workspace tools.

   Thirty tools went in at once, and every one of them wanted the same eight
   things: a two or three column row of fields, a muted line explaining why a
   field exists, a box for an answer, a tile for a figure, a table, a list of
   rows with a button on the end, and a block of monospace output. Writing
   those out on thirty pages would have been nine hundred copies of the same
   rule, and the check that watches for exactly that would have said so.

   So they live here, prefixed ws-, and a page's own <style> block carries
   only what is genuinely its own. Everything here inherits the same tokens
   as the rest of the site, so a colourway change reaches it without being
   told.
   --------------------------------------------------------------------------- */

.ws-g2, .ws-g3, .ws-g4 { display: grid; gap: 0 18px; }
.ws-g2 { grid-template-columns: 1fr 1fr; }
.ws-g3 { grid-template-columns: 1fr 1fr 1fr; }
.ws-g4 { grid-template-columns: 1fr 1fr 1fr 1fr; }

.ws-note { font: 12.5px/1.65 var(--font-sans); color: var(--ink-soft); margin: 10px 0 0; }
.ws-empty { font-size: 13.5px; color: var(--ink-soft); margin: 0; }

.ws-warn {
  font: 13px/1.65 var(--font-sans); color: var(--danger);
  background: var(--danger-soft); border: 1px solid var(--danger);
  border-radius: var(--radius-md); padding: 12px 15px; margin: 14px 0 0;
}
.ws-good {
  font: 13px/1.65 var(--font-sans); color: var(--ink);
  background: var(--paper-inset); border: 1px solid var(--rule-strong);
  border-radius: var(--radius-md); padding: 12px 15px; margin: 14px 0 0;
}

.ws-out {
  border: 1px solid var(--rule-strong); border-left: 4px solid var(--accent-strong);
  border-radius: var(--radius-md); padding: 15px 17px;
  background: var(--paper-inset); margin: 14px 0 0;
}
.ws-out.is-bad { border-left-color: var(--danger); background: var(--danger-soft); }

.ws-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin: 14px 0 0; }
.ws-fig {
  border: 1px solid var(--rule); border-left: 4px solid var(--accent-strong);
  border-radius: var(--radius-md); padding: 12px 14px; background: var(--paper-raised);
}
.ws-fig.is-bad { border-left-color: var(--danger); background: var(--danger-soft); }
.ws-fig > span {
  display: block; font: 600 11.5px var(--font-sans); text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft);
}
.ws-fig > strong { display: block; font: 700 23px/1.15 var(--font-mono); color: var(--ink); margin: 4px 0 0; }
.ws-fig > em { display: block; font-style: normal; font: 12.5px/1.6 var(--font-sans); color: var(--ink-soft); margin-top: 6px; }

.ws-table { width: 100%; border-collapse: collapse; font: 13.5px var(--font-sans); }
.ws-table th, .ws-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--rule); vertical-align: top; }
.ws-table thead th {
  font: 600 11.5px var(--font-sans); text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-soft); white-space: nowrap;
}
.ws-table td.num, .ws-table th.num { text-align: right; font-family: var(--font-mono); white-space: nowrap; }
.ws-table tbody th { font-weight: 600; color: var(--ink); }
/* A row worth a second look, and the reason it is worth one. The mark is a
   rule down the left rather than a wash of colour behind the text, so it
   reads the same in every colourway and cannot put the figures on a
   background they were not contrast checked against. */
.ws-table tbody tr.is-off > :first-child { box-shadow: inset 2px 0 0 var(--accent-strong); }
.ws-tag {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  border: 1px solid var(--rule); font: 500 11px var(--font-sans); color: var(--ink-soft);
  text-transform: none; letter-spacing: 0; white-space: nowrap; vertical-align: 1px;
}

.ws-list { list-style: none; margin: 0; padding: 0; }
.ws-list > li {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; padding: 11px 0; border-top: 1px solid var(--rule);
}
.ws-list > li:first-child { border-top: none; }
.ws-list b { display: block; font: 600 14px var(--font-sans); color: var(--ink); }
.ws-list span { display: block; font: 12.5px var(--font-mono); color: var(--ink-soft); margin-top: 2px; }
.ws-list i { display: block; font-style: normal; font: 12.5px/1.55 var(--font-sans); color: var(--ink-soft); margin-top: 4px; }
.ws-acts { display: flex; flex-wrap: wrap; gap: 7px; flex-shrink: 0; }

.btn-secondary.ws-small { padding: 6px 10px; font-size: 12px; }

pre.ws-pre {
  font: 13.5px/1.7 var(--font-mono); white-space: pre-wrap; word-break: break-word;
  background: var(--paper-inset); border: 1px solid var(--rule);
  border-radius: var(--radius-md); padding: 15px 17px; margin: 0; color: var(--ink);
}

textarea.ws-area {
  width: 100%; min-height: 110px; font: 13.5px/1.65 var(--font-sans);
  padding: 11px 12px; border: 1px solid var(--rule); border-radius: var(--radius-md);
  background: var(--paper-inset); color: var(--ink); resize: vertical;
}
textarea.ws-code { font-family: var(--font-mono); font-size: 13px; }

.ws-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 0; }
.ws-chip {
  font: 12px var(--font-mono); background: var(--paper-raised);
  border: 1px solid var(--rule); border-radius: 999px; padding: 3px 10px; color: var(--ink);
}
.ws-chip.is-bad { border-color: var(--danger); color: var(--danger); background: var(--danger-soft); }

@media (max-width: 820px) { .ws-g4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) {
  .ws-g2, .ws-g3, .ws-g4 { grid-template-columns: 1fr; }
  .ws-list > li { flex-direction: column; }
  .btn-secondary.ws-small { min-height: 44px; min-width: 44px; }
}
@media print {
  .os-topbar, .os-header, .os-footer, .action-row, .os-rel, .os-faq-link, .ws-acts { display: none !important; }
  .panel { break-inside: avoid; }
}
/* A preview drawn at the size it prints (LABELS, ENVELOPE, BADGE), scaled
   down on the screen to the column it sits in; --fit is set by the tool.
   Printing uses the real size. */
@media screen { .ob-fit { zoom: var(--fit, 1); } }
