/* Styles for the /tools pages — loaded AFTER /styles.css on tool pages only.
   Follows the site system: dark theme, neutral greys as hsl(0 0% L%), brand
   orange hsl(18 60% 55%) — softened from hsl(17 80% 55%) on 13-09-2026, channel values in multiples of 5. */

/* --- The interactive tool box (the "hero" of every tool page) --- */

/* `.article-content` dresses article imagery: `img` gets a 600px cap, 25px
   radius, drop shadow and 1.5rem margin, and `figure img` swaps that shadow for
   a three-layer white glow. Inside a tool both read as a halo around every
   picture, so UI images opt out here, once, rather than in each tool. The
   `figure` selector is spelled out because `.article-content figure img`
   out-ranks a two-part reset — and a card in the image grid IS a figure.
   Article imagery outside .tool-box keeps the treatment. */
.tool-box img,
.tool-box figure img {
  max-width: none;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
}

/* The same rule set gives every `figure` a 2rem block margin. A card in the
   image grid is a figure, and a grid track is sized to the item's MARGIN box —
   so that margin inflated every row by 64px and read as a hole between rows. */
.tool-box figure { margin: 0; }

.tool-box {
  background: hsl(0 0% 10%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 14px;
  padding: 1.5rem;
  margin: 2rem 0;
}

.tool-box label {
  display: block;
  font-size: 0.9rem;
  color: hsl(0 0% 65%);
  margin-bottom: 0.5rem;
}

/* The field and both buttons hold one row for as long as the field can stay
   260px wide; under that the button GROUP moves below it, whole. The group is
   what `.tool-share-actions` is for: plain `flex-wrap` used to send the last
   button down on its own between 641 and 715px, leaving one button beside the
   field and one under it. The form itself must never become a COLUMN — in a
   column the field's 260px flex-basis stops being a width and becomes its
   HEIGHT, which is how a 40px field grew to 260px on a phone. */
.tool-share-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.tool-share-form .tool-input,
.tool-input-slot { flex: 1 1 260px; }

.tool-share-actions { display: flex; gap: 0.75rem; }

/* The paste button (built by initShareForm wherever the clipboard API exists)
   hangs inside the field's right edge. The slot is its positioning context and
   is a grid so it hugs the field rather than adding an inline-block line box —
   which is also why the field needs `width: 100%` — and the field's extra
   padding keeps a long link from running under the button. */
.tool-input-slot { position: relative; display: grid; }
.tool-share-form .tool-input-slot .tool-input { width: 100%; padding-right: 2.5rem; }

.tool-paste {
  position: absolute;
  top: 50%;
  right: 5px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  background: none;
  border: none;
  border-radius: 6px;
  color: hsl(0 0% 60%);
  font-size: 1rem;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.tool-paste:hover { background: hsl(0 0% 100% / 0.1); color: hsl(0 0% 100%); }
.tool-paste:focus-visible { outline: 2px solid hsl(18 60% 55%); outline-offset: 2px; }

.tool-input,
.tool-textarea,
.tool-select {
  background: hsl(0 0% 7%);
  border: 1px solid hsl(0 0% 100% / 0.15);
  border-radius: 10px;
  color: hsl(0 0% 100%);
  font: inherit;
  padding: 0.75rem 1rem;
  transition: border-color 0.2s;
}

.tool-input { min-width: 0; }

.tool-input:focus,
.tool-textarea:focus,
.tool-select:focus {
  outline: none;
  border-color: hsl(18 60% 55%);
}

.tool-textarea {
  width: 100%;
  min-height: 180px;
  resize: vertical;
  line-height: 1.6;
}

.tool-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  background: hsl(18 60% 55%);
  color: hsl(0 0% 100%);
  border: none;
  border-radius: 10px;
  font: inherit;
  font-weight: 600;
  padding: 0.75rem 1.5rem;
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
}

.tool-btn:hover { background: hsl(18 60% 50%); transform: translateY(-1px); }
.tool-btn:focus, .tool-btn:focus-visible { outline: none; box-shadow: none; }
.tool-btn:disabled { opacity: 0.6; cursor: default; transform: none; }
.tool-btn.is-busy::after {
  content: '';
  width: 1em;
  height: 1em;
  border: 2px solid hsl(0 0% 100% / 0.4);
  border-top-color: hsl(0 0% 100%);
  border-radius: 50%;
  animation: tool-spin 0.7s linear infinite;
}

/* A 40px square has room for one thing: the spinner stands in for the icon
   rather than sitting on top of it. */
.tool-btn--icon.is-busy .bi { display: none; }

.tool-btn--ghost {
  background: hsl(0 0% 100% / 0.08);
  font-weight: 500;
}
.tool-btn--ghost:hover { background: hsl(0 0% 100% / 0.15); }

@keyframes tool-spin { to { transform: rotate(360deg); } }

.tool-error {
  color: hsl(0 75% 70%);
  background: hsl(0 75% 60% / 0.1);
  border: 1px solid hsl(0 75% 60% / 0.3);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  margin: 1rem 0 0;
}

.tool-hint {
  font-size: 0.85rem;
  color: hsl(0 0% 55%);
  margin-top: 0.75rem;
}

.tool-result { margin-top: 1.5rem; }

/* --- The bridge from a finished download to the extension ---
   One <dialog>, two treatments. `showModal()` on a desktop: the work is done
   by then, so this is the one moment on the page worth interrupting for, and
   tool.js spends it once per browser. On a coarse pointer it opens non-modally
   instead and the block at the end of this rule set puts it back in the flow
   as a quiet line under the grid — extensions install on a desktop browser, so
   a store button there would be a dead tap for the 93% of this page's search
   traffic that arrives on a phone. */
/* No `position` here on purpose: the UA gives an open dialog `fixed` (modal) or
   `absolute` (not), and overriding either one breaks the centring that comes
   with it — the modal lands in the top-left corner. It is positioned already,
   so the close button anchors to it without help. */
.tool-bridge {
  box-sizing: border-box;
  /* A modal dialog is centred by the UA's `margin: auto` against `inset: 0` —
     and styles.css opens with `* { margin: 0 }`, which wipes it and drops the
     card in the top-left corner. Put it back explicitly. */
  margin: auto;
  /* Wide enough for the rating badge and the button to share one line, the way
     they do at the foot of the page; below that the row wraps on its own.
     48px padding + 406px badge + 20px gap + 186px button = 660 exactly, so 660
     wrapped the moment the badge's separators were centred — re-measure this
     when either one changes. */
  width: min(690px, calc(100vw - 2rem));
  max-width: none;
  /* Top is trimmed rather than equal: the title inherits `.article-content p`'s
     1.8 line-height, so ~7px of half-leading sits above its cap and an equal
     24px would read as a hole. 0.9rem + that leading lands the text at the same
     25px the sides and the bottom keep. */
  padding: 0.9rem 1.5rem 1.5rem;
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 14px;
  background: hsl(0 0% 10%);
  color: hsl(0 0% 100%);
}
.tool-bridge::backdrop { background: hsl(0 0% 0% / 0.8); }

/* Opening a dialog focuses its first control — and on a phone that control is
   hidden, so focus lands on the block itself and Chrome rings the whole thing
   in blue. The focus move is worth keeping for screen readers, the ring is not;
   every control inside still draws its own. */
.tool-bridge:focus { outline: none; }

/* A row, not an absolutely-placed corner button: the title and the ✕ then sit
   on one line whatever the copy is, and neither needs a margin to dodge the
   other. */
.tool-bridge-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.4rem;
}

.tool-bridge-close {
  flex: none;
  /* The ✕ glyph floats in the middle of a 30px hit area, so it inherits the
     same slack on every side — which means it sits at `padding-top + slack`
     from the top but `padding-right + slack` from the edge, and the top
     padding is the trimmed one. Pull the box out by exactly that difference
     and the GLYPH lands at the same gap on both edges, whatever either padding
     later becomes; the hit area keeps its size. */
  margin-right: calc(0.9rem - 1.5rem);
  display: grid;
  place-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 8px;
  color: hsl(0 0% 55%);
  cursor: pointer;
}
.tool-bridge-close:hover { background: hsl(0 0% 100% / 0.1); color: hsl(0 0% 100%); }
/* showModal() focuses the first control, which is this one — so the ring is
   always on show for a moment and has to be ours, not Chrome's blue. */
.tool-bridge-close:focus-visible { outline: 2px solid hsl(18 60% 55%); outline-offset: 2px; }

/* `.article-content p` is (0,1,1) and out-ranks a lone class, so without this
   every paragraph in here keeps the article's 1rem bottom margin — which threw
   the header out of level: `align-items: center` centres MARGIN boxes, so the
   title sat 8px above the ✕ it was supposed to line up with. */
.tool-bridge p { margin: 0; }

/* Two classes, like the margin reset above and for the same reason: colour
   comes from `.article-content p` (0,1,1) otherwise, which painted the heading
   the body's grey. The body and the note keep that inherited grey on purpose —
   declaring one here would only be a second, quieter lie. */
.tool-bridge .tool-bridge-title {
  font-size: 1.05rem;
  font-weight: 600;
  color: hsl(0 0% 100%);
}
.tool-bridge-text { font-size: 0.9rem; }

/* Everything else about the row comes from .feature-cta; inside a dialog its
   2.5rem block margin and its centring are both wrong — the badge and the
   button line up with the paragraph's edges instead. */
.tool-bridge-cta {
  margin: 1.5rem 0 0;
  justify-content: space-between;
}

.tool-bridge-note { display: none; font-size: 0.85rem; }

@media (pointer: coarse) {
  .tool-bridge[open] {
    position: static;
    width: auto;
    margin: 1.5rem 0 0;
    padding: 1.5rem 0 0;
    border: 0;
    border-top: 1px solid hsl(0 0% 100% / 0.1);
    border-radius: 0;
    background: none;
  }
  .tool-bridge-close,
  .tool-bridge-cta { display: none; }
  .tool-bridge .tool-bridge-note { display: block; margin-top: 1rem; }
}

/* --- Stat tiles (summary / counters) --- */

.tool-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.75rem;
  margin: 1rem 0;
}

.tool-stat {
  background: hsl(0 0% 7%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 10px;
  padding: 0.9rem 1rem;
}

.tool-stat b {
  display: block;
  font-size: 1.5rem;
  line-height: 1.2;
  color: hsl(18 60% 60%);
  font-variant-numeric: tabular-nums;
}

.tool-stat span { font-size: 0.8rem; color: hsl(0 0% 60%); }

/* --- Transcript (viewer / print preview) --- */

.tool-transcript { display: flex; flex-direction: column; gap: 1rem; }

.tool-msg {
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 12px;
  padding: 1rem 1.25rem;
  overflow-wrap: break-word;
}

.tool-msg--user { background: hsl(0 0% 13%); }
.tool-msg--assistant { background: hsl(0 0% 9%); }

.tool-msg-role {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: hsl(0 0% 55%);
  margin-bottom: 0.5rem;
}

.tool-msg--user .tool-msg-role { color: hsl(18 60% 60%); }

.tool-msg-body { line-height: 1.65; }
.tool-msg-body > :first-child { margin-top: 0; }
.tool-msg-body > :last-child { margin-bottom: 0; }
.tool-msg-body p, .tool-msg-body ul, .tool-msg-body ol, .tool-msg-body pre,
.tool-msg-body table, .tool-msg-body blockquote { margin: 0.75rem 0; }
.tool-msg-body pre {
  background: hsl(0 0% 5%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  overflow-x: auto;
  font-size: 0.85rem;
}
.tool-msg-body code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.tool-msg-body p code, .tool-msg-body li code {
  background: hsl(0 0% 100% / 0.1);
  border-radius: 4px;
  padding: 0.1em 0.35em;
  font-size: 0.85em;
}
.tool-msg-body img { max-width: 100%; border-radius: 8px; }
.tool-msg-body a { color: hsl(18 60% 60%); }
.tool-msg-body blockquote {
  border-left: 3px solid hsl(0 0% 100% / 0.2);
  padding-left: 1rem;
  color: hsl(0 0% 75%);
}
.tool-msg-body table { border-collapse: collapse; display: block; overflow-x: auto; }
.tool-msg-body th, .tool-msg-body td {
  border: 1px solid hsl(0 0% 100% / 0.15);
  padding: 0.4rem 0.7rem;
  text-align: left;
}

/* --- Toolbars above results (format pickers, action rows) --- */

.tool-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: center;
  margin: 1rem 0;
}

/* --- Token visualization (token counter) --- */

.tool-tokens {
  background: hsl(0 0% 7%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 10px;
  padding: 0.9rem 1rem;
  line-height: 1.9;
  max-height: 300px;
  overflow-y: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.tool-token {
  border-radius: 4px;
  padding: 0.1em 0.05em;
}

/* 5-color rotation, brand-adjacent hues at low alpha */
.tool-token:nth-child(5n+1) { background: hsl(18 60% 55% / 0.3); }
.tool-token:nth-child(5n+2) { background: hsl(145 50% 50% / 0.25); }
.tool-token:nth-child(5n+3) { background: hsl(210 70% 55% / 0.3); }
.tool-token:nth-child(5n+4) { background: hsl(275 60% 60% / 0.3); }
.tool-token:nth-child(5n+5) { background: hsl(45 80% 55% / 0.25); }

/* --- Data tables (cost calculator) --- */

.tool-table-wrap { overflow-x: auto; margin: 1rem 0; }

.tool-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.tool-table th, .tool-table td {
  border-bottom: 1px solid hsl(0 0% 100% / 0.1);
  padding: 0.6rem 0.9rem;
  text-align: left;
  white-space: nowrap;
}

.tool-table th {
  color: hsl(0 0% 60%);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tool-table--prose th, .tool-table--prose td { white-space: normal; }
.tool-table--prose td:first-child { width: 14rem; } /* colour comes from the article table's label rail */

/* A three-column prose table crushes to five-character columns on a phone —
   the first column's 14rem alone eats the width. Give those a floor and let
   .tool-table-wrap scroll instead; two-column ones still wrap fine. */
@media (max-width: 600px) {
  .tool-table--prose:has(thead th:nth-child(3)) { min-width: 32rem; }
  .tool-table--prose:has(thead th:nth-child(3)) td:first-child { width: 9rem; }
}

/* Orange is the link colour on this site, so a bold run inside a prose table
   must not wear it — only the cost table below claims the accent back. */
.tool-table td b { color: hsl(0 0% 100%); font-variant-numeric: tabular-nums; }
.tool-table tr:hover td { background: hsl(0 0% 100% / 0.03); }
/* …without flattening the label rail, which is already tinted at rest. */
.tool-table tr:hover td:first-child { background: hsl(0 0% 100% / 0.07); }

.tool-inputs-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

/* Same trap as `.tool-input-slot` above: a grid track does not stretch an
   `<input>`, so without this the fields sit at their intrinsic width instead of
   filling the column. */
.tool-inputs-row .tool-input { width: 100%; }

/* --- Image downloader: result panel (.idl-*) ---
   Bar, card and count copy the extension's Chat Workspace: search grows on the
   left, the selected-count and its buttons sit at the right end. Every card is a
   fixed square in an even grid — the thumbnail crops, the RESOLUTION row and the
   carousel keep the file's real proportions. */

/* The divider sits ABOVE the result block — it separates the link row from the
   images. The chat title needs no second rule under it; the toolbar reads as a
   different layer on its own. */
.idl-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.75rem;
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid hsl(0 0% 100% / 0.1);
}

.idl-head h2 { margin: 0; font-size: 1.05rem; font-weight: 600; }

/* --- one control system across the whole widget ---
   40px tall, 8px radius, 0.9rem type, the same surfaces — the link field, its
   two buttons and every control in the result bar. Scoped to this tool: the
   other tool pages keep the shared .tool-input / .tool-btn sizing. */
.tool-box--idl .tool-input,
.tool-box--idl .tool-btn {
  height: 40px;
  box-sizing: border-box;
  border: 1px solid hsl(0 0% 100% / 0.15);
  border-radius: 8px;
  font-size: 0.9rem;
}

.tool-box--idl .tool-input {
  background: hsl(0 0% 100% / 0.05);
  padding: 0 0.85rem;
}

.tool-box--idl .tool-btn { padding: 0 1.1rem; }
.tool-box--idl .tool-btn--icon { width: 40px; padding: 0; }

/* `text-box` makes the box hug the letters: without it the title's 1.6
   line-height parked 6.6px of half-leading above its cap, so a uniform 24px
   padding read as 30.6px on top against 24px at the sides — the hole the owner
   points at. Trimming the bottom too is what makes `margin-bottom` honest:
   1.25rem is now the 20px actually seen, where 0.9rem used to draw ~22px. */
.tool-box .tool-box-title {
  margin: 0 0 1.25rem;
  text-box: trim-both cap alphabetic;
  font-size: 1.05rem;
  font-weight: 600;
  color: hsl(0 0% 100%);
}

.idl-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 1rem 0 1.25rem;
}

.idl-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 300px;
  min-width: 0;
  height: 38px;
  padding: 0 0.65rem;
  background: hsl(0 0% 100% / 0.05);
  border: 1px solid hsl(0 0% 100% / 0.15);
  border-radius: 8px;
  color: hsl(0 0% 60%);
  transition: border-color 0.2s;
}

.idl-search:focus-within { border-color: hsl(18 60% 55%); }

.idl-search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  color: hsl(0 0% 100%);
  font: inherit;
  font-size: 0.9rem;
}

.idl-search input:focus { outline: none; }
.idl-search input::-webkit-search-cancel-button { display: none; }

.idl-search-clear {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  padding: 0.25rem;
  line-height: 0;
  border-radius: 5px;
}

.idl-search-clear:hover { color: hsl(0 0% 100%); background: hsl(0 0% 100% / 0.1); }

.idl-tools {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  flex-wrap: wrap;
}

/* A readout, not a control: no surface, no border, no button height. The
   figure answers "how many of how many"; tabular figures keep the row from
   twitching as the count changes, and the denominator stays muted so the
   number that moves is the one you read. */
.idl-picked {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  height: 40px;
  white-space: nowrap;
}

.idl-figure {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.95rem;
  font-weight: 600;
  color: hsl(0 0% 100%);
  font-variant-numeric: tabular-nums;
}

/* <b> would come out at 700 and make the numerator heavier than the rest of
   the figure — the approved cut has one weight across it. */
.idl-figure b { font-weight: inherit; }
.idl-total { color: hsl(0 0% 40%); }
.idl-label { font-size: 0.8rem; color: hsl(0 0% 60%); }

/* Editable filename: plain text until you reach for it. */
.idl-name {
  width: 100%;
  min-width: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 5px;
  color: inherit;
  font: inherit;
  text-align: right;
  /* Fallback only: tool.js elides long names in the MIDDLE so the extension
     survives, and restores the whole name on focus. This catches whatever
     slips past it (a resize, a name pasted while focused). */
  text-overflow: ellipsis;
  padding: 0.05rem 0.3rem;
  /* The padding and border are the field's, not the column's — pulled back out
     so the name lines up with the values above it (and gets those ~12px back
     as room for the name itself, which a 240px card has none to spare of). */
  margin: 0 calc(-0.3rem - 1px);
  cursor: text;
}

/* No hover outline, and the alignment never changes — switching to left on
   focus made the whole name jump sideways the moment you clicked into it. */
.idl-name:focus {
  outline: none;
  border-color: hsl(18 60% 55%);
  background: hsl(0 0% 0% / 0.4);
  color: hsl(0 0% 100%);
}

.tool-btn--sm { padding: 0.5rem 0.85rem; font-size: 0.85rem; }

/* Icon-only actions: square, same 38px rhythm as the search box and the chip.
   Every one carries title + aria-label, since nothing else names them. */
/* One weight across the row: every action glyph is an outlined Bootstrap icon
   at the same em, so none of them needs a size of its own. Scoped like the rule
   above it on purpose — `.tool-box--idl .tool-btn` sets 0.9rem and out-ranks a
   lone class, which quietly shrank every glyph to 14px. */
.tool-box--idl .tool-btn--icon { font-size: 1.15rem; }

mark {
  background: hsl(18 60% 55% / 0.3);
  color: hsl(18 60% 75%);
  border-radius: 3px;
  padding: 0 0.1em;
}

/* --- cards --- */

/* max() caps it at three columns on a wide page and drops to two, then one, as
   the tracks would fall under 210px — what `columns: 3 210px` used to do, minus
   the column flow that left the first card hanging below its neighbours. */
.idl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(210px, (100% - 1.8rem) / 3), 1fr));
  gap: 0.9rem;
}

.idl-card {
  position: relative;
  background: hsl(0 0% 13%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 10px;
  overflow: hidden;
}

.idl-card[hidden] { display: none; }
.idl-card--off :is(.idl-shot, .idl-facts) { opacity: 0.4; }

/* Square cell: every card in a row starts and ends at the same place whatever
   shape the image is. The RESOLUTION row prints the real dimensions and the
   carousel shows the whole picture, so the thumbnail can afford the crop. */
.idl-shot {
  position: relative;
  display: block;
  aspect-ratio: 1;
  background: hsl(0 0% 9%);
  line-height: 0;
  cursor: zoom-in;
}

/* Two classes deep on purpose: `.article-content figure img` sets height:auto
   at the same specificity as a lone `.idl-shot img`, and a card IS a figure —
   the image kept its natural height and painted over the rows below it. */
.idl-card .idl-shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.idl-overlay {
  position: absolute;
  inset: auto 0 0 0;
  padding: 1.75rem 0.75rem 0.6rem;
  background: linear-gradient(to top, hsl(0 0% 0% / 0.9), transparent);
}

.idl-card-title {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.35;
  color: hsl(0 0% 100%);
  text-shadow: 0 1px 3px hsl(0 0% 0% / 0.7);
}

/* The checkbox sits over the image, so it keeps full opacity while an
   unselected card fades — otherwise you cannot see what you are re-ticking. */
.idl-tick {
  position: absolute;
  top: 0.55rem;
  right: 0.55rem;
  appearance: none;
  width: 22px;
  height: 22px;
  margin: 0;
  cursor: pointer;
  background: hsl(0 0% 0% / 0.6);
  border: 1px solid hsl(0 0% 100% / 0.2);
  border-radius: 6px;
  display: grid;
  place-content: center;
}

.idl-tick::after {
  content: '';
  width: 11px;
  height: 6px;
  border-left: 2px solid hsl(0 0% 100%);
  border-bottom: 2px solid hsl(0 0% 100%);
  transform: rotate(-45deg) translate(1px, -1px);
  opacity: 0;
}

.idl-tick:checked { background: hsl(18 60% 55%); border-color: hsl(18 60% 55%); }
.idl-tick:checked::after { opacity: 1; }
.idl-tick:focus-visible { outline: 2px solid hsl(18 60% 55%); outline-offset: 2px; }

.idl-facts { margin: 0; }

.idl-fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4rem 0.75rem;
  border-top: 1px solid hsl(0 0% 100% / 0.1);
}

.idl-fact[hidden] { display: none; }

.idl-fact dt {
  flex: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: hsl(0 0% 50%);
}

.idl-fact dd {
  margin: 0;
  min-width: 0;
  text-align: right;
  font-size: 0.78rem;
  color: hsl(0 0% 75%);
  overflow-wrap: anywhere;
}

/* Two lines, then an ellipsis — one long prompt used to make its card twice
   the height of the row it sits in. */
.idl-fact dd[data-hit="prompt"] {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.idl-fact:not(:first-child) dd {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: hsl(0 0% 60%);
}

/* --- full-screen carousel --- */

/* --- Result placeholder, painted while the share is fetched ---
   The markup (tool.js → SKELETON) reuses .idl-head / .idl-bar / .idl-grid /
   .idl-card / .idl-fact, so every box lands where the real one will; these
   rules only paint the grey bars inside them. Scoped under .idl-skel so
   `.idl-shot.idl-sk` out-ranks .idl-shot's own background wherever this block
   ends up in the file. */
.idl-skel .idl-sk {
  display: block;
  background: linear-gradient(90deg, hsl(0 0% 100% / 0.05) 25%, hsl(0 0% 100% / 0.1) 50%, hsl(0 0% 100% / 0.05) 75%);
  background-size: 300% 100%;
  animation: idl-sk-sweep 1.5s linear infinite;
}
.idl-skel .idl-shot { cursor: default; }
.idl-skel .idl-sk-title { width: 40%; max-width: 14rem; height: 1.05rem; border-radius: 6px; }
.idl-skel .idl-sk-line { width: 60%; height: 0.8rem; border-radius: 5px; }
.idl-skel .idl-sk-count { width: 5.5rem; height: 1rem; border-radius: 5px; }
.idl-skel .idl-sk-btn { width: 40px; height: 40px; border-radius: 8px; }
.idl-skel .idl-sk-dt { width: 4.5rem; height: 0.65rem; border-radius: 4px; }
.idl-skel .idl-sk-dd { width: 5.5rem; height: 0.7rem; border-radius: 4px; }

@keyframes idl-sk-sweep {
  from { background-position: 150% 50%; }
  to { background-position: -50% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .idl-skel .idl-sk { animation: none; }
}

.idl-lb {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  box-sizing: border-box;
  padding: 0.9rem;
  border: 0;
  background: hsl(0 0% 5%);
  color: hsl(0 0% 100%);
  /* minmax(0, 1fr), not 1fr: a bare 1fr row is floored at the image's own
     height, so a tall portrait overflows and prints the caption over itself. */
  grid-template-rows: auto minmax(0, 1fr) auto;
}

.idl-lb[open] { display: grid; }
.idl-lb::backdrop { background: hsl(0 0% 0% / 0.8); }

.idl-lb-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8rem;
  color: hsl(0 0% 55%);
}

.idl-lb-close {
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  padding: 0.35rem 0.5rem;
  border-radius: 6px;
}

.idl-lb-close:hover { background: hsl(0 0% 100% / 0.1); color: hsl(0 0% 100%); }

.idl-lb-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  min-height: 0;
  overflow: hidden;
}

.idl-lb-stage img {
  /* Height-driven on purpose: with a width-driven box, `object-fit: contain`
     letterboxes the picture inside a box that still spans the row — and the
     arrows, sitting at that box's edges, end up against the window. Driving
     from the height makes the box hug the picture, so the gap beside it is the
     flex gap and nothing else. */
  height: 100%;
  width: auto;
  max-width: 100%;
  max-height: calc(100vh - 12rem);
  object-fit: contain;
  border-radius: 8px;
  box-shadow: none;
}

.idl-lb-nav {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  cursor: pointer;
  background: hsl(0 0% 100% / 0.1);
  border: 1px solid hsl(0 0% 100% / 0.2);
  color: hsl(0 0% 100%);
  font-size: 1.5rem;
  line-height: 1;
}

.idl-lb-nav:hover { background: hsl(0 0% 100% / 0.2); }

.idl-lb-foot { text-align: center; padding-top: 0.75rem; max-width: 70ch; margin: 0 auto; }
.idl-lb-foot p { margin: 0 0 0.25rem; }
.idl-lb-title { font-weight: 600; }
.idl-lb-prompt { font-size: 0.9rem; color: hsl(0 0% 75%); }

.idl-lb-meta {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  color: hsl(0 0% 55%);
}

@media (max-width: 600px) {
  .idl-grid { grid-template-columns: 1fr; }
  .idl-tools { margin-left: 0; }
}

/* --- Prompt library --- */

.tool-chipbar {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 1rem 0;
}

.tool-chip {
  background: hsl(0 0% 100% / 0.08);
  border: 1px solid transparent;
  border-radius: 999px;
  color: hsl(0 0% 80%);
  font: inherit;
  font-size: 0.85rem;
  padding: 0.35rem 0.9rem;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}

.tool-chip:hover { background: hsl(0 0% 100% / 0.15); }
.tool-chip:focus, .tool-chip:focus-visible { outline: none; box-shadow: none; }
.tool-chip.is-active {
  background: hsl(18 60% 55% / 0.2);
  border-color: hsl(18 60% 55%);
  color: hsl(18 60% 65%);
}

.tool-prompt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.75rem;
  margin: 1rem 0;
}

.tool-prompt-card {
  background: hsl(0 0% 10%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 12px;
  padding: 1rem 1.15rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.tool-prompt-card h3 { font-size: 1rem; margin: 0; }

.tool-prompt-card p {
  font-size: 0.85rem;
  color: hsl(0 0% 65%);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 1;
}

.tool-prompt-card .tool-btn { align-self: flex-start; padding: 0.4rem 0.9rem; font-size: 0.85rem; }

/* --- Word counter: two-column shell, metric rail, gauge, word frequency --- */

/* `display: flex` below out-ranks the UA [hidden] rule — restore it. */
.wc-options[hidden], .wc-stat[hidden] { display: none; }

.wc-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 270px;
  gap: 1rem;
}

/* The paste control can't live inside a <textarea>, so it floats over one,
   parked one line below the placeholder and hidden as soon as there's text.
   Flex, so the field stretches to whatever height the metric rail ends up at
   (the grid row stretches both columns) instead of leaving dead space. */
.wc-input-wrap { position: relative; display: flex; }
.wc-main .tool-textarea { flex: 1; min-height: 340px; }

.wc-paste {
  position: absolute;
  top: 3.1rem; /* textarea padding-top (0.75rem) + one 1.6 line + a gap */
  left: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.9rem;
  background: hsl(0 0% 15%);
  border: 1px solid hsl(0 0% 100% / 0.15);
  border-radius: 8px;
  color: hsl(0 0% 75%);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}

.wc-paste:hover { background: hsl(0 0% 20%); border-color: hsl(18 60% 55%); color: hsl(18 60% 60%); }
.wc-paste:focus, .wc-paste:focus-visible { outline: none; box-shadow: none; }
.wc-paste[hidden] { display: none; }

/* --- Collapsible panels (Metrics, Keyword density) --- */

.wc-side { display: flex; flex-direction: column; gap: 1rem; }

/* Each panel is its own card — a lifted surface with a tinted header band, so
   the title reads as a lid on the list rather than as one more row of it.
   --wc-head-h keeps the gear aligned with the summary row it sits beside, and
   --wc-pad is the card's inner gutter that every child indents by. */
.wc-panel {
  --wc-head-h: 2.4rem;
  --wc-pad: 0.75rem;
  position: relative;
  background: hsl(0 0% 13%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 10px;
}

.wc-panel summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  height: var(--wc-head-h);
  padding: 0 var(--wc-pad);
  background: hsl(0 0% 100% / 0.05);
  border-bottom: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 9px 9px 0 0;
  cursor: pointer;
  list-style: none;
}

.wc-panel details[open] { padding-bottom: 0.4rem; }
/* Collapsed, the header band IS the card — round it off and drop the divider. */
.wc-panel details:not([open]) summary { border-bottom: none; border-radius: 9px; }
.wc-panel summary::-webkit-details-marker { display: none; }
.wc-panel summary:focus-visible { outline: 2px solid hsl(25 100% 66%); outline-offset: 2px; border-radius: 6px; }
.wc-panel summary .bi { color: hsl(0 0% 50%); font-size: 0.75rem; flex-shrink: 0; transition: transform 0.2s ease; }
.wc-panel details[open] summary .bi { transform: rotate(180deg); color: hsl(18 60% 60%); }

@media (prefers-reduced-motion: reduce) {
  .wc-panel summary .bi { transition: none; }
}

.wc-title {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: hsl(0 0% 70%);
}

.wc-gear {
  position: absolute;
  top: 0;
  right: calc(var(--wc-pad) + 1.6rem);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: var(--wc-head-h);
  background: none;
  border: none;
  color: hsl(0 0% 55%);
  font-size: 0.9rem;
  cursor: pointer;
  transition: color 0.2s;
}

.wc-gear:hover, .wc-gear[aria-expanded="true"] { color: hsl(18 60% 60%); }
.wc-gear:focus, .wc-gear:focus-visible { outline: none; box-shadow: none; }

/* One button cycling the keyword list through 10 -> 20 -> 50 -> 100. It sits
   OUTSIDE <summary> for the same reason as the gear, and takes the gear's slot
   on its own panel. */
.wc-topn {
  position: absolute;
  top: calc((var(--wc-head-h) - 1.4rem) / 2);
  right: calc(var(--wc-pad) + 1.6rem);
  display: inline-flex;
  align-items: center;
  height: 1.4rem;
  padding: 0 0.45rem;
  background: hsl(0 0% 100% / 0.06);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 6px;
  color: hsl(0 0% 60%);
  font: inherit;
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}

.wc-topn:hover { background: hsl(0 0% 100% / 0.1); border-color: hsl(18 60% 55% / 0.5); color: hsl(18 60% 60%); }
.wc-topn:focus, .wc-topn:focus-visible { outline: none; box-shadow: none; }

/* Anchored to .wc-panel rather than the top layer — a native popover can't sit
   under the gear without CSS anchor positioning. */
.wc-options {
  position: absolute;
  top: calc(var(--wc-head-h) + 0.4rem);
  right: 0;
  z-index: 5;
  width: 250px;
  max-height: 360px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.5rem;
  background: hsl(0 0% 13%);
  border: 1px solid hsl(0 0% 100% / 0.15);
  border-radius: 10px;
  box-shadow: 0 10px 30px hsl(0 0% 0% / 0.5);
}

/* `.tool-box label` (0,1,1) out-ranks a bare class — scope these to win. */
.tool-box .wc-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.3rem 0.4rem;
  border-radius: 6px;
  font-size: 0.85rem;
  color: hsl(0 0% 80%);
  cursor: pointer;
}

.tool-box .wc-option:hover { background: hsl(0 0% 100% / 0.06); }
.tool-box .wc-option input { accent-color: hsl(18 60% 55%); flex: none; }

.wc-reset {
  margin-top: 0.4rem;
  padding: 0.4rem;
  background: hsl(0 0% 100% / 0.08);
  border: none;
  border-radius: 8px;
  color: hsl(0 0% 70%);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}

.wc-reset:hover { background: hsl(0 0% 100% / 0.15); color: hsl(0 0% 100%); }
.wc-reset:focus, .wc-reset:focus-visible { outline: none; box-shadow: none; }

/* --- Metric rail --- */

.wc-rail { display: flex; flex-direction: column; padding: 0.1rem var(--wc-pad) 0; }

.wc-stat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid hsl(0 0% 100% / 0.05);
}

/* .is-last, not :last-child — the rail renders all 18 rows and hides the
   switched-off ones, so the DOM's last child is rarely the visible one. */
.wc-stat.is-last { border-bottom: none; }
.wc-stat span { font-size: 0.8rem; color: hsl(0 0% 60%); }
.wc-stat b {
  font-size: 1.05rem;
  color: hsl(18 60% 60%);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- Token counter: presets, stat tiles, summary cards, price table --- */

/* This tool is a single stacked column rather than the word counter's
   textarea + side rail: every block below reads top to bottom as one flow,
   because each one depends on the one above it. */
.tc-box { display: flex; flex-direction: column; }

/* The 8-column price table needs more room than the 800px prose column, so the
   tool box alone breaks out to the container's full width. 100cqw resolves
   against .tc-page's content box, which is exactly the width the prose sits in
   — no 100vw scrollbar guesswork. */
.tc-page { container-type: inline-size; }

@container (width >= 52rem) {
  .article-content .tc-box {
    width: 100cqw;
    position: relative;
    left: 50%;
    translate: -50% 0;
  }
}

.tc-presets {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.tc-presets-label { font-size: 0.8rem; color: hsl(0 0% 50%); flex: none; }
.tc-presets .tool-chipbar { margin: 0; flex: 1 1 auto; }

/* Paste / Clear sit in the action row below the box, not floating over it —
   the word counter's overlay button only works because that textarea starts
   empty, and Clear shows precisely when there is text under it. */
.tc-input-wrap { display: flex; }
.tc-input-wrap .tool-textarea { flex: 1; min-height: 220px; }

.tc-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-top: 1rem;
  background: hsl(0 0% 7%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 12px;
  overflow: hidden;
}

.tc-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 1.1rem 0.75rem;
  text-align: center;
  border-left: 1px solid hsl(0 0% 100% / 0.1);
}

.tc-tile:first-child { border-left: none; }

.tc-tile b {
  font-size: 2.2rem;
  line-height: 1.1;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.tc-tile--accent b { color: hsl(18 60% 60%); }

.tc-tile-label {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: hsl(0 0% 60%);
}

.tc-tile-sub { font-size: 0.75rem; color: hsl(0 0% 45%); font-variant-numeric: tabular-nums; }

.tc-viz-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

.tc-util-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.85rem;
  font-size: 0.85rem;
  font-family: inherit;
  color: hsl(0 0% 85%);
  background: hsl(0 0% 100% / 0.06);
  border: 1px solid hsl(0 0% 100% / 0.12);
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.tc-util-btn:hover { background: hsl(0 0% 100% / 0.12); border-color: hsl(18 60% 55% / 0.5); color: hsl(18 60% 60%); }
.tc-util-btn:focus, .tc-util-btn:focus-visible { outline: none; box-shadow: none; }
/* inline-flex would otherwise beat the UA [hidden] rule */
.tc-util-btn[hidden] { display: none; }
.tc-util-btn[aria-expanded="true"] { background: hsl(18 60% 55% / 0.15); border-color: hsl(18 60% 55% / 0.5); color: hsl(18 60% 60%); }

/* The price table is the second half of the same tool, not a second tool — a
   rule separates it inside the one .tool-box instead of a new card. */
.tc-cost {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid hsl(0 0% 100% / 0.1);
}

.article-content .tc-cost-title { font-size: 1.15rem; margin: 0 0 1rem; }

/* Reads as a sentence, so the two numbers that drive every figure below are
   visibly assumptions rather than results. */
.tc-assume {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: hsl(0 0% 60%);
}

.tc-assume-input {
  width: 5.5rem;
  padding: 0.35rem 0.5rem;
  font-family: inherit;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: hsl(18 60% 60%);
  background: hsl(0 0% 7%);
  border: 1px solid hsl(0 0% 100% / 0.15);
  border-radius: 8px;
}

.tc-assume-input:focus { outline: none; border-color: hsl(18 60% 55%); }
.tc-assume-x { color: hsl(0 0% 35%); }

.tc-cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.tc-card {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1rem 1.1rem;
  background: hsl(0 0% 7%);
  border: 1px solid hsl(0 0% 100% / 0.1);
  border-radius: 12px;
}

/* Only the cheap side takes the accent — the eye should land on the saving. */
.tc-card--cheap { border-color: hsl(18 60% 55% / 0.4); background: hsl(18 60% 55% / 0.06); }

.tc-card-label {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: hsl(0 0% 50%);
}

.tc-card b {
  font-size: 1.6rem;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.tc-card--cheap b { color: hsl(18 60% 60%); }
.tc-card-model { font-size: 0.9rem; color: hsl(0 0% 85%); }
.tc-card-note { font-size: 0.75rem; color: hsl(0 0% 50%); }

.tc-providers { margin-bottom: 0.75rem; }
.tc-providers .tool-chip { display: inline-flex; align-items: center; gap: 0.4rem; }
.tc-chip-count { font-size: 0.75rem; color: hsl(0 0% 45%); font-variant-numeric: tabular-nums; }
.tool-chip.is-active .tc-chip-count { color: inherit; opacity: 0.7; }
.tc-logo { flex: none; opacity: 0.85; }

.tc-utils {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

/* flex would otherwise beat the UA [hidden] rule — showPricingError() hides this
   row, and Copy MD/CSV on an empty table would otherwise flash "Copied". */
.tc-utils[hidden] { display: none; }

.tc-utils .tc-search { flex: 1 1 220px; min-width: 0; padding: 0.45rem 0.75rem; font-size: 0.85rem; }

/* Eight columns need every pixel, so the table bleeds to the card's edges and
   only the outer cells keep the card's own 1.5rem gutter. */
.tc-box .tool-table-wrap { margin-inline: -1.5rem; }

/* The cost table sits inside .article-content, so the prose table's look reaches
   it — but it is data, not prose: no label rail down the model column, and it
   keeps the header band its sortable columns were built on. */
.article-content .tc-table { background: hsl(0 0% 7%); border: none; border-radius: 12px; }
.tc-table thead th {
  background: hsl(0 0% 15%);
  color: hsl(0 0% 100%);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  padding: 0.75rem 1rem;
}
.tc-table tbody td { padding: 0.75rem 1rem; vertical-align: middle; }
.tc-table thead th:first-child { background: hsl(0 0% 15%); border-right: none; }
.tc-table tbody td:first-child { background: none; border-right: none; }
.tc-table tbody td.tc-model { color: hsl(0 0% 90%); font-weight: 400; }
.tc-table th { padding: 0; }
.tc-table td { padding-inline: 0.5rem; }
.tc-table td:first-child { padding-inline-start: 1.5rem; }
.tc-table td:last-child { padding-inline-end: 1.5rem; }
.tc-table th:first-child .tc-sort { padding-inline-start: 1.5rem; }
.tc-table th:last-child .tc-sort { padding-inline-end: 1.5rem; }

/* The whole header cell is the sort target, so the hit area matches the cell. */
.tc-sort {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  width: 100%;
  padding: 0.7rem 0.5rem;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
  white-space: nowrap;
}

.tc-sort::after {
  content: '\2195';
  font-size: 0.85em;
  color: hsl(0 0% 40%);
}

.tc-sort:hover { color: hsl(0 0% 100%); }
.tc-sort:hover::after { color: hsl(0 0% 65%); }
.tc-sort:focus, .tc-sort:focus-visible { outline: none; box-shadow: none; }
.tc-sort:focus-visible { color: hsl(18 60% 60%); }

.tc-table th[aria-sort="ascending"] .tc-sort,
.tc-table th[aria-sort="descending"] .tc-sort { color: hsl(18 60% 60%); }
.tc-table th[aria-sort="ascending"] .tc-sort::after { content: '\2191'; color: hsl(18 60% 60%); }
.tc-table th[aria-sort="descending"] .tc-sort::after { content: '\2193'; color: hsl(18 60% 60%); }

.tc-table .tc-num { text-align: right; font-variant-numeric: tabular-nums; }
/* The monthly-cost column: a figure the tool computed, not prose — it keeps the accent. */
.tc-table td b { color: hsl(18 60% 60%); }
.tc-table th.tc-num .tc-sort { justify-content: flex-end; }
/* `.article-content tbody td` (0,1,2) sets every cell to 80%, so the model name
   needs two classes to win — the row's label reads a shade brighter than its
   numbers. */
.tc-table .tc-model { display: flex; align-items: center; gap: 0.5rem; color: hsl(0 0% 90%); }

#tc-token-note { margin-top: 0.5rem; }
#tc-token-note b { color: hsl(0 0% 75%); font-weight: 600; }

/* Below 700px the rate and context columns go: Model / Tokens / per request /
   per month are the four that answer "what does this cost me", and the model's
   logo already carries the provider. */
@media (width < 700px) {
  .tc-tiles { grid-template-columns: 1fr; }
  .tc-tile { border-left: none; border-top: 1px solid hsl(0 0% 100% / 0.1); padding: 0.85rem; }
  .tc-tile:first-child { border-top: none; }
  .tc-tile b { font-size: 1.8rem; }
  .tc-cards { grid-template-columns: 1fr; }
  .tc-table .tc-col-provider,
  .tc-table .tc-col-rate,
  .tc-table .tc-col-context { display: none; }
  /* Long names like "Gemini 3.1 Flash-Lite" are what force the sideways
     scroll once the table is down to four columns. */
  .tc-table .tc-model { white-space: normal; }
  /* "PER REQUEST"/"PER MONTH" are wider than any value under them. */
  .tc-th-prefix { display: none; }
  .tc-table td:first-child, .tc-table th:first-child .tc-sort { padding-inline-start: 1rem; }
  .tc-table td:last-child, .tc-table th:last-child .tc-sort { padding-inline-end: 1rem; }
}

/* --- Social post-length gauge --- */

/* .wc-panel supplies the card shell (same as Metrics / Keyword density); this
   block is only the gauge's own guts. */
.wc-gauge { margin-top: 1.25rem; }

.wc-gauge-body { padding: 0.9rem var(--wc-pad) 0.3rem; }

.wc-gauge-icons { position: relative; height: 1.6rem; }
.wc-gauge-scale { position: relative; height: 1.2rem; }

/* One mark per LENGTH, not per network. Networks that recommend the same count
   stack like the landing page's ratings face pile and fan out on hover — the
   group's translateX(-50%) is of its own width, so it opens symmetrically
   around its tick and the centre never drifts. */
.wc-gauge-mark {
  position: absolute;
  bottom: 0;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
}

.wc-gauge-face {
  display: flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  margin-left: -14px;
  background: hsl(0 0% 20%);
  border: 2px solid hsl(0 0% 13%); /* the card colour — cuts each circle out of the one behind it */
  border-radius: 50%;
  color: hsl(0 0% 90%);
  font-size: 0.9rem;
  transition: margin-left 0.2s ease, color 0.2s, opacity 0.2s;
}

.wc-gauge-face:first-child { margin-left: 0; }
.wc-gauge-mark:hover .wc-gauge-face { margin-left: 0.2rem; }
.wc-gauge-mark:hover .wc-gauge-face:first-child { margin-left: 0; }
.wc-gauge-mark.is-over .wc-gauge-face { color: hsl(0 0% 45%); opacity: 0.5; }

@media (prefers-reduced-motion: reduce) {
  .wc-gauge-face { transition: color 0.2s, opacity 0.2s; }
}

/* The live character count rides above the dot. --at is clamped in tool.js so
   the label can't hang off the card at either end of the track. */
.wc-gauge-value { position: relative; height: 1.3rem; }

.wc-gauge-count {
  position: absolute;
  bottom: 0;
  left: var(--at, 0%);
  transform: translateX(-50%);
  font-size: 0.8rem;
  font-weight: 600;
  color: hsl(18 60% 60%);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: left 0.2s;
}

.wc-gauge-track {
  position: relative;
  height: 8px;
  margin: 0.5rem 0 0.4rem;
  background: hsl(0 0% 100% / 0.1);
  border-radius: 999px;
}

.wc-gauge-fill {
  position: absolute;
  inset: 0 auto 0 0;
  z-index: 1;
  width: 0;
  background: hsl(18 60% 55%);
  border-radius: 999px;
  transition: width 0.2s;
}

/* Above the fill, so the band separators stay readable once it covers them. */
.wc-gauge-notch {
  position: absolute;
  top: -1px;
  z-index: 2;
  width: 3px;
  height: 10px;
  margin-left: -1.5px;
  background: hsl(0 0% 13%);
}

.wc-gauge-dot {
  position: absolute;
  top: 50%;
  z-index: 3;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  transform: translateY(-50%);
  background: hsl(18 60% 55%);
  border: 2px solid hsl(0 0% 13%);
  border-radius: 50%;
  transition: left 0.2s;
}

.wc-gauge-scale span {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 0.75rem;
  color: hsl(0 0% 55%);
  font-variant-numeric: tabular-nums;
}

/* --- Keyword density (right rail, so rows carry their own bar as a backdrop) --- */

.article-content .wc-empty {
  margin: 0.6rem 0 0;
  padding: 0 var(--wc-pad) 0.35rem;
  font-size: 0.8rem;
  line-height: 1.5;
  color: hsl(0 0% 45%);
}

.article-content .wc-freq-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0 0.4rem;
  display: grid;
  gap: 0.15rem;
  max-height: 24rem;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: hsl(0 0% 100% / 0.2) transparent;
}

.article-content .wc-freq-list li {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.3rem 0.45rem;
  font-size: 0.8rem;
  border-radius: 5px;
  overflow: hidden;
}

.wc-freq-fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: hsl(18 60% 55% / 0.15);
  border-radius: 5px;
}

.wc-freq-list li > :not(.wc-freq-fill) { position: relative; }
.wc-freq-word { color: hsl(0 0% 85%); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wc-freq-list b { color: hsl(0 0% 90%); font-variant-numeric: tabular-nums; }
.wc-freq-list small { color: hsl(0 0% 50%); font-variant-numeric: tabular-nums; }

/* Marks sit 14% apart, so on a phone a two-network stack would touch its
   neighbour at 30px a face — shrink the pile instead of crowding the track. */
@media (max-width: 560px) {
  .wc-gauge-face { width: 24px; height: 24px; margin-left: -11px; font-size: 0.75rem; }
  .wc-gauge-mark:hover .wc-gauge-face { margin-left: 0.1rem; }
  .wc-gauge-mark:hover .wc-gauge-face:first-child { margin-left: 0; }
}

@media (max-width: 820px) {
  .wc-main { grid-template-columns: 1fr; }
  .wc-main .tool-textarea { min-height: 220px; }
}

/* --- Tools hub index cards reuse .blog-card from styles.css --- */

/* --- Print tool: what the print stylesheet keeps --- */

@media print {
  body.tool-printing > *:not(.tool-print-area) { display: none !important; }
  body.tool-printing .tool-print-area { display: block !important; }
  .tool-print-area { color: hsl(0 0% 0%); background: hsl(0 0% 100%); }
  .tool-print-area .tool-msg { border-color: hsl(0 0% 60%); break-inside: avoid; }
  .tool-print-area .tool-msg--user, .tool-print-area .tool-msg--assistant { background: hsl(0 0% 100%); }
}

@media (max-width: 640px) {
  .tool-box { padding: 1rem; }
  .tool-share-actions { flex: 1 1 100%; flex-direction: column; }
  .tool-btn { width: 100%; }
  .tool-actions .tool-btn { width: auto; flex: 1 1 auto; }
}
