/* ============================================================
   TOOLYARD — GLOBAL DESIGN SYSTEM
   Shared across all pages. Import first.
============================================================ */

/* Google Fonts loaded in each HTML file */

:root {
  /* Colors — Dark mode defaults */
  --bg: #0a0a0f;
  --bg2: #111118;
  --bg3: #18181f;
  --surface: #1c1c26;
  --surface2: #22222e;
  --surface3: #2a2a38;
  --border: rgba(255,255,255,0.07);
  --border2: rgba(255,255,255,0.12);
  --border3: rgba(255,255,255,0.18);

  /* Brand */
  --accent: #7c6cff;
  --accent2: #a78bfa;
  --accent3: #38bdf8;
  --accent-glow: rgba(124,108,255,0.25);

  /* Semantic */
  --green: #34d399;
  --green-bg: rgba(52,211,153,0.1);
  --orange: #fb923c;
  --orange-bg: rgba(251,146,60,0.1);
  --red: #f87171;
  --red-bg: rgba(248,113,113,0.1);
  --yellow: #fbbf24;
  --yellow-bg: rgba(251,191,36,0.1);

  /* Typography */
  --text: #f0f0f8;
  --text2: #a0a0b8;
  --text3: #6b6b88;
  --text4: #44445a;

  /* Shadows */
  --shadow-sm: 0 1px 4px rgba(0,0,0,0.3);
  --shadow: 0 4px 24px rgba(0,0,0,0.4);
  --shadow-lg: 0 8px 48px rgba(0,0,0,0.5);
  --shadow-accent: 0 4px 24px rgba(124,108,255,0.3);

  /* Radii */
  --r-sm: 6px;
  --r: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-full: 9999px;

  /* Fonts */
  --font-display: 'Syne', sans-serif;
  --font-body: 'Inter', sans-serif;
  --font-mono: 'Fira Code', 'Courier New', monospace;

  /* Transitions */
  --t: 0.18s cubic-bezier(0.4, 0, 0.2, 1);
  --t-slow: 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  --t-spring: 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Layout */
  --max-w: 1280px;
  --header-h: 64px;
}

[data-theme="light"] {
  --bg: #f8f8fc;
  --bg2: #ffffff;
  --bg3: #f0f0f8;
  --surface: #ffffff;
  --surface2: #f5f5fd;
  --surface3: #ededf8;
  --border: rgba(0,0,0,0.07);
  --border2: rgba(0,0,0,0.11);
  --border3: rgba(0,0,0,0.16);
  --text: #0d0d1a;
  --text2: #4a4a6a;
  --text3: #8080a0;
  --text4: #b0b0c8;
  --shadow-sm: 0 1px 4px rgba(0,0,0,0.06);
  --shadow: 0 4px 24px rgba(0,0,0,0.08);
  --shadow-lg: 0 8px 48px rgba(0,0,0,0.12);
  --shadow-accent: 0 4px 24px rgba(124,108,255,0.2);
}

/* ── RESET ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; }
body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  overflow-x: hidden;
  /* A long URL, hash, Base64 blob or token with no spaces in it establishes a
     min-content width that nothing can shrink, which pushes its container —
     and then the page — wider than the screen. The result boxes already set
     `word-break: break-all`; this covers prose, table cells, card text and
     anything added later. break-word only breaks words that would otherwise
     overflow, so ordinary text still wraps at spaces. */
  overflow-wrap: break-word;
  transition: background var(--t-slow), color var(--t-slow);
}
a { color: inherit; text-decoration: none; }
img, video { max-width: 100%; display: block; }
button { cursor: pointer; border: none; background: none; font-family: inherit; color: inherit; }
input, textarea, select { font-family: inherit; }
ul, ol { list-style: none; }

/* Scrollbar */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--surface3); border-radius: 99px; }

/* Selection */
::selection { background: rgba(124,108,255,0.3); }

/* ── LAYOUT UTILITIES ── */
.container { max-width: var(--max-w); margin: 0 auto; padding: 0 24px; }
.section-pad { padding: 80px 0; }
.section-pad-sm { padding: 48px 0; }

/* ── TYPOGRAPHY SCALE ── */
.display-1 {
  font-family: var(--font-display);
  font-size: clamp(44px, 7vw, 96px);
  font-weight: 800;
  line-height: 1.03;
  letter-spacing: -0.03em;
}
.display-2 {
  font-family: var(--font-display);
  font-size: clamp(32px, 5vw, 64px);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.025em;
}
.display-3 {
  font-family: var(--font-display);
  font-size: clamp(24px, 3.5vw, 44px);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.02em;
}
.heading-1 { font-size: 28px; font-weight: 700; line-height: 1.2; }
.heading-2 { font-size: 22px; font-weight: 700; line-height: 1.25; }
.heading-3 { font-size: 18px; font-weight: 600; line-height: 1.3; }
.body-lg { font-size: 18px; line-height: 1.7; color: var(--text2); }
.body { font-size: 15px; line-height: 1.65; }
.body-sm { font-size: 13px; line-height: 1.6; }
.caption { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text3); }
.mono { font-family: var(--font-mono); font-size: 13px; }

/* Gradient text */
.grad-text {
  background: linear-gradient(135deg, var(--accent2) 0%, var(--accent3) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.grad-text-warm {
  background: linear-gradient(135deg, var(--orange) 0%, var(--yellow) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* ── COMPONENTS ── */

/* Section label */
.section-label {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent2);
  margin-bottom: 12px;
}

/* Pill / Badge */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  font-size: 12px;
  font-weight: 600;
  background: rgba(124,108,255,0.12);
  color: var(--accent2);
  border: 1px solid rgba(124,108,255,0.2);
}
.pill-green { background: var(--green-bg); color: var(--green); border-color: rgba(52,211,153,0.2); }
.pill-orange { background: var(--orange-bg); color: var(--orange); border-color: rgba(251,146,60,0.2); }
.pill-red { background: var(--red-bg); color: var(--red); border-color: rgba(248,113,113,0.2); }
.pill-neutral { background: var(--surface2); color: var(--text2); border-color: var(--border2); }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 11px 22px;
  border-radius: var(--r);
  font-size: 14px;
  font-weight: 600;
  transition: all var(--t);
  white-space: nowrap;
  position: relative;
  overflow: hidden;
}
.btn:active { transform: scale(0.98) !important; }
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover {
  background: var(--accent2);
  box-shadow: var(--shadow-accent);
  transform: translateY(-1px);
}
.btn-secondary {
  background: var(--surface);
  color: var(--text2);
  border: 1px solid var(--border2);
}
.btn-secondary:hover {
  border-color: var(--accent2);
  color: var(--accent2);
  transform: translateY(-1px);
}
.btn-ghost {
  color: var(--text2);
  padding: 11px 16px;
}
.btn-ghost:hover { background: var(--surface); color: var(--text); }
.btn-danger { background: var(--red-bg); color: var(--red); border: 1px solid rgba(248,113,113,0.2); }
.btn-danger:hover { background: var(--red); color: #fff; }
.btn-sm { padding: 7px 14px; font-size: 13px; }
.btn-lg { padding: 15px 32px; font-size: 16px; border-radius: var(--r-md); }
.btn-icon { padding: 10px; width: 40px; height: 40px; }

/* Ripple effect */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255,255,255,0.1);
  opacity: 0;
  transition: opacity 0.3s;
}
.btn:active::after { opacity: 1; }

/* Cards */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  transition: all var(--t);
}
.card-hover:hover {
  border-color: var(--border2);
  box-shadow: var(--shadow);
  transform: translateY(-3px);
}
.card-body { padding: 24px; }
.card-body-lg { padding: 32px; }

/* Inputs */
.input-base {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 11px 14px;
  font-size: 14px;
  color: var(--text);
  outline: none;
  transition: border-color var(--t), box-shadow var(--t);
}
.input-base::placeholder { color: var(--text3); }
.input-base:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(124,108,255,0.12);
}
.input-base:disabled { opacity: 0.5; cursor: not-allowed; }
textarea.input-base { min-height: 100px; resize: vertical; }
select.input-base { cursor: pointer; }

/* Label */
.field-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text3);
  text-transform: uppercase;
  margin-bottom: 7px;
}

/* Progress */
.progress { height: 6px; background: var(--surface2); border-radius: 99px; overflow: hidden; }
.progress-fill {
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--accent), var(--accent3));
  transition: width 0.5s cubic-bezier(0.4,0,0.2,1);
}

/* Divider */
.divider { height: 1px; background: var(--border); }
.divider-v { width: 1px; background: var(--border); align-self: stretch; }

/* Grid */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; }
.grid-4 { display: grid; grid-template-columns: repeat(4,1fr); gap: 16px; }
.grid-auto { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }

/* ── RESPONSIVE GRID UTILITIES ──
   For grids that were declared in a `style=""` attribute. That is not a style
   preference — an inline declaration beats every stylesheet rule that is not
   `!important`, so a grid written inline is multi-column at EVERY viewport and
   no media query anywhere can collapse it. A phone got three 36px numbers in
   95px columns, or two `datetime-local` inputs (which have a ~190px intrinsic
   width in Chrome) in 155px ones.

   These carry only `display` and `grid-template-columns`; gap, margin and
   alignment stay inline at the call site, because those were never the
   problem. The breakpoint is 560px rather than the 768px used elsewhere in
   this file: at 600-700px two columns are still comfortable and collapsing
   that early wastes a tablet's width.

   Grids that are FINE in two columns on a phone — pairs of short buttons,
   checkbox rows, preset chips — were deliberately left inline. So was the
   scientific calculator's 5-column keypad, which has to stay a keypad. */
.rgrid-2 { display: grid; grid-template-columns: 1fr 1fr; }
.rgrid-3 { display: grid; grid-template-columns: repeat(3,1fr); }
/* input · linked-ratio toggle · input */
.rgrid-split { display: grid; grid-template-columns: 1fr auto 1fr; }
/* narrow column beside a wide one, e.g. a heading beside its FAQ list. The
   gap lives here rather than inline because 64px between two stacked blocks
   is a sixth of a phone screen of dead space. */
.rgrid-aside { display: grid; grid-template-columns: 1fr 1.5fr; gap: 64px; }
@media (max-width: 560px) {
  .rgrid-2, .rgrid-3, .rgrid-split, .rgrid-aside { grid-template-columns: 1fr; }
  .rgrid-aside { gap: 28px; }
  /* The split row's middle cell is a chain/lock toggle sitting between two
     fields; centre it once the row becomes a column. */
  .rgrid-split > * { justify-self: stretch; }
}

/* Flex helpers */
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.gap-4 { gap: 4px; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.gap-24 { gap: 24px; }
.gap-32 { gap: 32px; }
.flex-1 { flex: 1; }
.flex-wrap { flex-wrap: wrap; }

/* Spacing */
.mt-4 { margin-top: 4px; }
.mt-8 { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.mt-32 { margin-top: 32px; }
.mt-48 { margin-top: 48px; }
.mb-8 { margin-bottom: 8px; }
.mb-16 { margin-bottom: 16px; }
.mb-24 { margin-bottom: 24px; }
.mb-32 { margin-bottom: 32px; }
.p-16 { padding: 16px; }
.p-24 { padding: 24px; }
.p-32 { padding: 32px; }

/* Text colors */
.text-accent { color: var(--accent2); }
.text-green { color: var(--green); }
.text-orange { color: var(--orange); }
.text-red { color: var(--red); }
.text-muted { color: var(--text2); }
.text-faint { color: var(--text3); }
.text-center { text-align: center; }

/* ── ANIMATIONS ── */
@keyframes fadeIn { from{opacity:0} to{opacity:1} }
@keyframes fadeUp { from{opacity:0;transform:translateY(20px)} to{opacity:1;transform:translateY(0)} }
@keyframes fadeDown { from{opacity:0;transform:translateY(-10px)} to{opacity:1;transform:translateY(0)} }
@keyframes scaleIn { from{opacity:0;transform:scale(0.94)} to{opacity:1;transform:scale(1)} }
@keyframes slideLeft { from{opacity:0;transform:translateX(20px)} to{opacity:1;transform:translateX(0)} }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }
@keyframes spin { to{transform:rotate(360deg)} }
@keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }
@keyframes float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-8px)} }

.animate-fade-in { animation: fadeIn 0.4s ease both; }
.animate-fade-up { animation: fadeUp 0.5s ease both; }
.animate-scale-in { animation: scaleIn 0.3s ease both; }
.animate-float { animation: float 5s ease-in-out infinite; }

/* Skeleton loading */
.skeleton {
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface2) 50%, var(--surface) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--r);
}

/* ── SHARED HEADER ── */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--header-h);
  z-index: 200;
  background: rgba(10,10,15,0.82);
  backdrop-filter: blur(20px) saturate(180%);
  border-bottom: 1px solid var(--border);
  transition: background var(--t-slow);
}
[data-theme="light"] .site-header {
  background: rgba(248,248,252,0.88);
}
.site-header-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 24px;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 28px;
}
.site-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  text-decoration: none;
}
.site-logo-text {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 800;
}
.site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
}
.site-nav a, .site-nav button {
  padding: 7px 14px;
  border-radius: var(--r);
  font-size: 14px;
  font-weight: 500;
  color: var(--text2);
  transition: background var(--t), color var(--t);
  text-decoration: none;
}
.site-nav a:hover, .site-nav button:hover { background: var(--surface); color: var(--text); }
.site-nav a.active { color: var(--accent2); }

/* ── BREADCRUMB ── */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text3);
  margin-bottom: 24px;
}
.breadcrumb a { color: var(--text3); transition: color var(--t); }
.breadcrumb a:hover { color: var(--accent2); }
.breadcrumb-sep { color: var(--text4); }
.breadcrumb-current { color: var(--text2); }

/* ── TOOL RESULT BOX ── */
.result-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 14px 16px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--accent2);
  min-height: 52px;
  word-break: break-all;
  line-height: 1.6;
}

/* ── BACK TO TOP ── */
.back-to-top {
  position: fixed;
  bottom: 28px; left: 28px;
  width: 44px; height: 44px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border2);
  display: flex; align-items: center; justify-content: center;
  color: var(--text2); font-size: 18px;
  cursor: pointer;
  z-index: 100;
  opacity: 0; visibility: hidden;
  transition: all var(--t);
  box-shadow: var(--shadow);
}
.back-to-top.show { opacity: 1; visibility: visible; }
.back-to-top:hover { background: var(--accent); border-color: var(--accent); color: #fff; transform: translateY(-2px); }

/* ── TOAST ── */
.toast-stack {
  position: fixed;
  bottom: 28px; right: 28px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 9999;
}
.toast {
  background: var(--surface);
  border: 1px solid var(--border2);
  border-radius: var(--r-md);
  padding: 13px 18px;
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; font-weight: 500;
  box-shadow: var(--shadow-lg);
  max-width: 340px;
  animation: slideLeft 0.3s ease;
}
.toast-success { border-left: 3px solid var(--green); }
.toast-error { border-left: 3px solid var(--red); }
.toast-info { border-left: 3px solid var(--accent2); }

/* ── AD SLOTS ── */
.ad-slot {
  background: var(--surface);
  border: 1px dashed var(--border2);
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text3);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.ad-leaderboard { width: 100%; height: 90px; }
.ad-rectangle { width: 300px; height: 250px; }
.ad-banner { width: 100%; height: 60px; }
.ad-skyscraper { width: 160px; height: 600px; }

/* ── HORIZONTAL SCROLL STRIPS ──
   Injected by ScrollStrip in core.js around the category/tab rows. The
   wrapper is a plain block whose only job is to position the two arrows; the
   strip inside keeps all of its own layout. Nothing renders until the strip
   actually overflows, so a short tab row is untouched. */
/* min-width:0 is load-bearing. Several tab bars (.tool-tabs on the colour
   page, for one) are flex containers, so this wrapper becomes a flex item —
   and a flex item's automatic minimum size is its CONTENT width, which here
   is every tab laid end to end. The strip it replaced was a scroll container,
   whose automatic minimum is 0, so it shrank correctly. Without this the
   colour page laid out 845px wide inside a 360px viewport. */
.strip-wrap { position: relative; min-width: 0; max-width: 100%; }
.strip-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px;
  display: none; align-items: center; justify-content: center;
  border-radius: var(--r-full);
  background: var(--surface2);
  border: 1px solid var(--border2);
  color: var(--text2);
  font-size: 17px; line-height: 1;
  box-shadow: var(--shadow-sm);
  z-index: 3;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.strip-arrow.show { display: flex; }
.strip-arrow:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.strip-arrow-l { left: 2px; }
.strip-arrow-r { right: 2px; }

/* A fade under each arrow so chips slide out of view rather than being cut
   off mid-glyph. ::before/::after on the wrapper, shown only while the
   matching arrow is. Pointer-events off so swiping still works through it. */
.strip-wrap::before, .strip-wrap::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 54px;
  pointer-events: none; opacity: 0; transition: opacity var(--t); z-index: 2;
}
.strip-wrap::before { left: 0; background: linear-gradient(90deg, var(--bg2), transparent); }
.strip-wrap::after { right: 0; background: linear-gradient(270deg, var(--bg2), transparent); }
.strip-wrap:has(.strip-arrow-l.show)::before { opacity: 1; }
.strip-wrap:has(.strip-arrow-r.show)::after { opacity: 1; }

/* Touch devices get momentum scrolling and no arrows: a thumb can already
   swipe the row, and 30px buttons sitting over the first and last chip would
   cover the thing they are meant to reveal. */
@media (hover: none) and (pointer: coarse) {
  .strip-arrow { display: none !important; }
}

/* ── MOBILE NAV DRAWER ──
   Built by MobileNav in core.js from the page's own header links. Hidden
   above 768px, which is exactly where .header-nav / nav.hide-mobile stop
   being hidden — so there is never a width showing both or neither. */
.mnav-toggle {
  display: none;
  width: 40px; height: 40px;
  flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  border-radius: var(--r); background: var(--surface);
  border: 1px solid var(--border2);
  flex-shrink: 0; margin-left: 8px;
}
.mnav-toggle span {
  display: block; width: 17px; height: 2px; border-radius: 2px;
  background: var(--text2); transition: transform var(--t), opacity var(--t);
}
.mnav-toggle.open span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.mnav-toggle.open span:nth-child(2) { opacity: 0; }
.mnav-toggle.open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.mnav-panel {
  position: fixed; inset: 0; z-index: 999;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(4px);
  opacity: 0; visibility: hidden;
  transition: opacity var(--t), visibility var(--t);
}
.mnav-panel.open { opacity: 1; visibility: visible; }
.mnav-sheet {
  position: absolute; top: var(--header-h); left: 0; right: 0;
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  padding: 10px 16px 16px;
  display: flex; flex-direction: column;
  transform: translateY(-10px);
  transition: transform var(--t);
  max-height: calc(100vh - var(--header-h)); overflow-y: auto;
}
.mnav-panel.open .mnav-sheet { transform: translateY(0); }
.mnav-link {
  padding: 14px 12px;
  font-size: 15px; font-weight: 600; color: var(--text);
  border-radius: var(--r);
  border-bottom: 1px solid var(--border);
}
.mnav-link:last-child { border-bottom: 0; }
.mnav-link:hover { background: var(--surface); color: var(--accent2); }

@media (max-width: 768px) { .mnav-toggle { display: flex; } }
@media (min-width: 769px) { .mnav-panel { display: none; } }

/* ── RESPONSIVE ── */
@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(2,1fr); }
}
@media (max-width: 768px) {
  .container { padding: 0 16px; }
  .section-pad { padding: 48px 0; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .site-nav { display: none; }
  .display-1 { font-size: 36px; }
  .display-2 { font-size: 28px; }
  .hide-mobile { display: none !important; }

  /* ── the header nav is hidden on mobile; its theme toggle should not be ──
     Every page except the homepage puts the theme button INSIDE
     `<nav class="… hide-mobile">`, next to the nav links. The rule above then
     took the button down with the links, so on 92 of 96 pages a phone had no
     way to switch between light and dark at all — the control existed, was
     documented, and was simply unreachable.

     So keep the nav box and hide only the links inside it. `nav.hide-mobile`
     is specific enough: that exact markup appears 92 times and nowhere else,
     and it is always the site header's nav. Scoped with the element selector
     rather than :has() so it does not depend on selector support.

     The nav links themselves are still gone on mobile. That is the existing
     design, and every page carries the same links in its footer — but a
     proper drawer is the obvious next step and is NOT done here. */
  nav.hide-mobile { display: flex !important; }
  /* Every direct link, not just `.hnav`. The AI Prompt Library's header uses
     `.header-nav-link` for the same job, and a `.hnav`-only selector left its
     six links visible once the nav was un-hidden — which pushed the menu
     button to x=518 in a 360px viewport, i.e. off the screen entirely. The
     theme button is a <button>, so it stays. */
  nav.hide-mobile > a { display: none; }

  /* The header is a non-wrapping flex row in a fixed bar, so anything it
     cannot fit runs off the right edge rather than reflowing. Tighten the
     gutter and the gap on a phone, and let the logo text shrink rather than
     push the menu button out: `min-width: 0` is needed because a flex item
     defaults to `min-width: auto` and so refuses to go below its text. */
  /* Two class names deep on purpose. The AI Prompt Library declares its own
     `.site-header-inner { gap: 24px }` in a page <style>, which loads after
     this file and wins at equal specificity — leaving its header 24px-gapped
     and pushing the menu button off the right edge at 320px. */
  .site-header .site-header-inner { padding: 0 14px; gap: 10px; }
  .site-header-inner > a:first-child { min-width: 0; overflow: hidden; }
  .site-header-inner .logo-text { white-space: nowrap; }

  /* ── let collapsed grids actually shrink ──
     Every layout below drops to a single column at some mobile breakpoint,
     and every one of them was still too wide, because a grid item's default
     `min-width: auto` sizes the track to the item's CONTENT rather than to
     the container. Measured on the homepage: a 437.7px track inside 262px of
     space, which made the document 487px wide and scroll sideways at 360px.

     `min-width: 0` is the standard release valve and is what `.tp-article`,
     `.post-body`, `.blog-lead-body` and `.pdf-file-body` already set
     individually — this generalises that to the collapsing containers instead
     of waiting for each one to be found by hand. Scoped to mobile so desktop
     track sizing, where content legitimately sets the width, is untouched. */
  .picker-layout > *, .grad-layout > *, .contrast-layout > *, .conv-layout > *,
  .two-col > *, .three-col > *, .base-display > *, .cb-row > *,
  .tp-body > *, .post-layout > *, .prompts-layout > *, .req-layout > *,
  .cl-layout > *, .color-output-grid > *, .tool-row > *, .result-grid > *,
  .mission-grid > *, .color-input-row > *, .regex-input-row > *,
  .grid-2 > *, .grid-3 > *, .grid-4 > *,
  .rgrid-2 > *, .rgrid-3 > *, .rgrid-split > *, .rgrid-aside > * {
    min-width: 0;
  }
}

/* ── 320px: the smallest screen still worth supporting ──
   Everything above is enough at 360px, which is the modern floor. These last
   few only misbehave on an older/smaller handset, and each is a box that
   cannot shrink rather than a layout that failed to collapse. */
@media (max-width: 360px) {
  /* A fit-content pill group of three tabs measures ~306px against ~272px of
     usable width. Let it wrap onto a second row instead of pushing the page. */
  .json-mode-tabs { width: auto; max-width: 100%; flex-wrap: wrap; }
  /* Swatch + hex field + picker side by side needs ~330px. */
  .color-input-row { flex-wrap: wrap; }
  .color-input-row .hex-text-input { flex: 1 1 140px; font-size: 16px; }
}
@media (min-width: 769px) {
  .hide-desktop { display: none !important; }
}

/* ── SHARED TOOL WORKSPACE ──
   Emitted by assets/js/tools.js render() bodies. Kept here rather than in
   a page so every consumer of the shared tool engine picks them up. */
.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
}
.workspace-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.ws-tab {
  padding: 9px 16px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text2);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: all var(--t, 0.18s);
  white-space: nowrap;
}
.ws-tab:hover { color: var(--text); }
.ws-tab.active {
  color: var(--accent2);
  border-bottom-color: var(--accent);
}
