/* ==========================================================================
   JebaTech — Design System
   Dark-mode-first tokens inspired by 21st.dev / shadcn-ui.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces */
  --bg:            #09090b;
  --bg-elevated:   #0d0d10;
  --surface:       #18181b;
  --surface-2:     #1f1f23;
  --surface-3:     #27272a;
  --overlay:       rgba(9, 9, 11, .72);

  /* Lines */
  --ring:          #27272a;
  --ring-strong:   #3f3f46;
  --ring-focus:    #ffb47a;   /* hsl( 26, 100%, 74%) — brand-tinted focus ring */

  /* Text */
  --fg:            #fafafa;
  --fg-muted:      #a1a1aa;
  --fg-subtle:     #85858f;   /* 4.85:1 on --surface; #71717a measured only 3.67 */
  --fg-inverse:    #09090b;

  /* Brand — sampled directly from logo.jpeg.
     The mark is a burnt orange sitting at hue 22–25° with ~95% saturation:
       #BC4B04  85.0% of the logo's chromatic pixels  hsl(23, 96%, 38%)
       #D86C22  11.2%                                 hsl(24, 72%, 49%)
     --brand-deep is that exact core colour. --brand lifts the same hue to
     52% lightness so it carries enough contrast against the near-black
     surfaces; the deep tone stays for gradient ends and pressed states. */
  --brand:         #f86e12;   /* hsl( 24, 94%, 52%) — primary interactive accent */
  --brand-hover:   #e05606;   /* hsl( 22, 95%, 45%) — hover / pressed           */
  --brand-deep:    #bc4b04;   /* hsl( 23, 96%, 38%) — exact logo core           */
  --brand-lift:    #ff9a47;   /* hsl( 27,100%, 64%) — highlights                */
  --brand-tint:    #ffcba3;   /* hsl( 26,100%, 82%) — text on soft brand fills  */
  --brand-soft:    rgba(248, 110, 18, .14);
  --brand-ring:    rgba(248, 110, 18, .40);
  /* Brand used as TEXT needs more contrast than brand used as a FILL. Keeping
     them separate lets the light theme darken links without also darkening
     the primary button, whose dark ink depends on a bright fill. */
  --brand-text:    #f86e12;
  --accent:        #ffb05c;   /* hsl( 28, 100%, 68%) — gradient far end         */
  --accent-soft:   rgba(255, 176, 92, .12);

  /* Semantic — hues chosen to stay legible beside an orange brand.
     Danger leans rose rather than red so it never reads as a brand tone. */
  --ok:            #34d399;   /* hsl(160, 64%, 51%) */
  --ok-soft:       rgba(52, 211, 153, .12);
  --warn:          #fbbf24;   /* hsl( 45, 96%, 56%) */
  --warn-soft:     rgba(251, 191, 36, .12);
  --danger:        #fb6a82;   /* hsl(350, 95%, 70%) */
  --danger-soft:   rgba(251, 106, 130, .12);

  /* Radii */
  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-full: 999px;

  /* Elevation */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow-md: 0 4px 16px -2px rgba(0,0,0,.55);
  --shadow-lg: 0 24px 60px -18px rgba(0,0,0,.75);
  --glow:      0 0 0 1px var(--brand-ring), 0 12px 40px -12px rgba(248,110,18,.45);

  /* Spacing scale */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;
  --s-12: 48px; --s-16: 64px; --s-20: 80px;

  /* Type */
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", "Noto Sans", "Noto Sans Arabic", "Noto Sans SC",
               "Noto Sans Devanagari", Arial, sans-serif;
  --font-mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* Motion */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --dur-fast: .14s;
  --dur: .24s;
  --dur-slow: .4s;

  /* Layout */
  --nav-h: 64px;
  --maxw: 1240px;
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);

  color-scheme: dark;
}

/* Light theme override — opt-in via the navbar toggle. */
[data-theme="light"] {
  --bg:            #fdfaf7;
  --bg-elevated:   #ffffff;
  --surface:       #ffffff;
  --surface-2:     #f7f3ef;
  --surface-3:     #ece5de;
  --overlay:       rgba(253, 250, 247, .78);
  --ring:          #ebe4dc;
  --ring-strong:   #d9cec3;
  --fg:            #09090b;
  --fg-muted:      #52525b;
  --fg-subtle:     #6b6b75;
  --fg-inverse:    #fafafa;
  --shadow-sm: 0 1px 2px rgba(9,9,11,.06);
  --shadow-md: 0 4px 16px -2px rgba(9,9,11,.10);
  --shadow-lg: 0 24px 60px -18px rgba(9,9,11,.18);

  /* The dark palette's accents are far too light on a near-white ground:
     measured on #fdfaf7 they came in at 1.61–2.79:1. These darker siblings
     hold the same hues above the 4.5:1 AA threshold for normal text.
     --brand itself stays bright because it is a FILL here (the primary
     button's dark ink needs it); only --brand-text darkens. */
  --brand-text:    #bc4b04;   /* 4.87:1 — and the exact logo colour */
  --brand-tint:    #9a3d03;   /* readable on the soft brand wash       */
  /* A focus indicator must clear 3:1 against its background (WCAG 2.4.11).
     The dark theme's #ffb47a measures only 1.67:1 on this near-white ground. */
  --ring-focus:    #bc4b04;   /* 4.87:1 */
  --ok:            #0f7a52;   /* 5.15:1 */
  --ok-soft:       rgba(15, 122, 82, .12);
  --warn:          #8a5a00;   /* 5.70:1 */
  --warn-soft:     rgba(138, 90, 0, .12);
  --danger:        #c81e3e;   /* 5.44:1 */
  --danger-soft:   rgba(200, 30, 62, .10);

  color-scheme: light;
}

/* --------------------------------------------------------------------------
   2. Reset / base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: -0.011em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

/* Ambient brand glow behind the app shell. */
body::before {
  content: "";
  position: fixed;
  inset: -40% 0 auto 0;
  height: 620px;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(60% 55% at 22% 32%, rgba(248,110,18,.17), transparent 68%),
    radial-gradient(50% 48% at 78% 18%, rgba(255,176,92,.11), transparent 70%);
  filter: blur(6px);
}
[data-theme="light"] body::before { opacity: .55; }

img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }

/* Baseline size for every JT_ICONS glyph. Component rules below (.btn svg,
   .tool-icon svg, …) are more specific and override this as needed; without
   it an icon in an unstyled container stretches to fill the box. */
.jt-icon { width: 18px; height: 18px; flex: none; }

h1, h2, h3, h4 {
  margin: 0 0 var(--s-3);
  font-weight: 650;
  line-height: 1.22;
  letter-spacing: -0.028em;
  text-wrap: balance;
}
h1 { font-size: clamp(2rem, 1.3rem + 3vw, 3.25rem); }
h2 { font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.85rem); }
h3 { font-size: clamp(1.05rem, .98rem + .4vw, 1.2rem); }
p  { margin: 0 0 var(--s-4); }
p, li { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--brand-text); }

ul, ol { margin: 0 0 var(--s-4); padding-inline-start: 1.35em; }
li { margin-bottom: var(--s-2); }

code, pre, kbd, samp { font-family: var(--font-mono); font-size: .875em; }
code:not(pre code) {
  background: var(--surface-2);
  border: 1px solid var(--ring);
  border-radius: var(--r-xs);
  padding: .12em .42em;
}
pre {
  background: var(--surface);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  padding: var(--s-4);
  overflow-x: auto;
}

hr { border: 0; border-top: 1px solid var(--ring); margin: var(--s-8) 0; }

::selection { background: var(--brand-ring); color: #fff; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ring-focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--surface-3) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-full);
}
*::-webkit-scrollbar-thumb:hover { background: var(--ring-strong); background-clip: content-box; }

/* --------------------------------------------------------------------------
   3. Utilities
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: max(var(--s-5), var(--safe-l)) max(var(--s-5), var(--safe-r));
}
@media (max-width: 640px) {
  .container { padding-inline: max(var(--s-4), var(--safe-l)) max(var(--s-4), var(--safe-r)); }
}

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.skip-link {
  position: absolute;
  inset-inline-start: var(--s-4);
  top: -200%;
  z-index: 200;
  background: var(--brand);
  color: #1a0c02;
  padding: var(--s-3) var(--s-5);
  border-radius: var(--r-md);
  font-weight: 650;
}
.skip-link:focus { top: calc(var(--safe-t) + var(--s-3)); color: #1a0c02; }

.muted   { color: var(--fg-muted); }
.subtle  { color: var(--fg-subtle); }
.mono    { font-family: var(--font-mono); }
.center  { text-align: center; }
.nowrap  { white-space: nowrap; }
.hidden, [hidden] { display: none !important; }
.stack > * + * { margin-top: var(--s-4); }
.row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }

.gradient-text {
  background: linear-gradient(100deg, var(--fg) 8%, var(--brand) 52%, var(--accent) 96%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* --------------------------------------------------------------------------
   4. Controls — buttons, inputs, pills, switches
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--surface-2);
  --btn-fg: var(--fg);
  --btn-ring: var(--ring);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: 0 var(--s-4);
  border: 1px solid var(--btn-ring);
  border-radius: var(--r-md);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: inherit;
  font-size: .9rem;
  font-weight: 550;
  line-height: 1;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              opacity var(--dur-fast) var(--ease);
}
.btn:hover { background: var(--surface-3); border-color: var(--ring-strong); color: var(--fg); }
.btn:active { transform: translateY(1px) scale(.988); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.btn svg { width: 17px; height: 17px; flex: none; }

/* Dark ink on the brand orange rather than white. White on #f86e12 is only
   2.9:1 — below the WCAG AA floor — whereas #1a0c02 measures 6.6:1 on the
   brand and 9.1:1 on the lightest gradient stop, so the vivid logo hue is
   kept without shipping unreadable buttons. */
.btn-primary {
  --btn-bg: linear-gradient(180deg, var(--brand-lift) 0%, var(--brand) 55%, var(--brand-hover) 100%);
  --btn-fg: #1a0c02;
  --btn-ring: transparent;
  font-weight: 640;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .18);
  box-shadow: 0 1px 0 rgba(255,255,255,.3) inset, 0 8px 24px -10px rgba(248,110,18,.8);
}
.btn-primary:hover {
  --btn-bg: linear-gradient(180deg, #ffae66 0%, #fb7a22 55%, #d64f03 100%);
  color: #1a0c02;
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset, 0 12px 30px -10px rgba(248,110,18,.95);
}

.btn-ghost { --btn-bg: transparent; --btn-ring: transparent; }
.btn-ghost:hover { --btn-bg: var(--surface-2); border-color: var(--ring); }

.btn-danger { --btn-bg: var(--danger-soft); --btn-fg: var(--danger); --btn-ring: rgba(251,106,130,.28); }
.btn-danger:hover { --btn-bg: rgba(251,106,130,.22); color: var(--danger); }

.btn-sm { min-height: 36px; padding: 0 var(--s-3); font-size: .82rem; border-radius: var(--r-sm); }
.btn-lg { min-height: 52px; padding: 0 var(--s-6); font-size: 1rem; border-radius: var(--r-lg); }
.btn-icon { width: 44px; min-height: 44px; padding: 0; }
.btn-icon.btn-sm { width: 36px; min-height: 36px; }
.btn-block { width: 100%; }

.input, .textarea, .select {
  width: 100%;
  min-height: 44px;
  padding: var(--s-3) var(--s-4);
  background: var(--bg-elevated);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  color: var(--fg);
  font: inherit;
  font-size: .92rem;
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--fg-subtle); }
.input:hover, .textarea:hover, .select:hover { border-color: var(--ring-strong); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}
.textarea { min-height: 180px; resize: vertical; font-family: var(--font-mono); font-size: .85rem; line-height: 1.65; }
.select {
  appearance: none;
  padding-inline-end: var(--s-10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a1a1aa' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-3) center;
  background-size: 17px;
  cursor: pointer;
}
[dir="rtl"] .select { background-position: left var(--s-3) center; }

.field { display: block; margin-bottom: var(--s-4); }
.label {
  display: block;
  margin-bottom: var(--s-2);
  font-size: .8rem;
  font-weight: 600;
  color: var(--fg-muted);
  letter-spacing: .01em;
}
.hint { margin: var(--s-2) 0 0; font-size: .78rem; color: var(--fg-subtle); }

/* Range slider */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 26px;
  background: transparent;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: var(--r-full);
  /* --_p is kept in sync with the value by JT.bindRangeFill(). */
  background: linear-gradient(90deg, var(--brand) var(--_p, 50%), var(--surface-3) var(--_p, 50%));
}
input[type="range"]::-moz-range-track { height: 6px; border-radius: var(--r-full); background: var(--surface-3); }
input[type="range"]::-moz-range-progress { height: 6px; border-radius: var(--r-full); background: var(--brand); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px; height: 20px;
  margin-top: -7px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--brand);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--brand);
}
input[type="range"]:hover::-webkit-slider-thumb { transform: scale(1.12); box-shadow: 0 0 0 6px var(--brand-soft); }

input[type="color"] {
  width: 48px; height: 44px;
  padding: 3px;
  background: var(--bg-elevated);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  cursor: pointer;
}
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
input[type="color"]::-webkit-color-swatch { border: none; border-radius: var(--r-sm); }

/* Checkbox / switch */
.check {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 44px;
  cursor: pointer;
  user-select: none;
  font-size: .9rem;
}
.check input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 20px; height: 20px;
  flex: none;
  margin: 0;
  border: 1.5px solid var(--ring-strong);
  border-radius: var(--r-xs);
  background: var(--bg-elevated);
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.check input[type="checkbox"]:checked { background: var(--brand); border-color: var(--brand); }
.check input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  inset-inline-start: 6px; top: 2px;
  width: 5px; height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}

.switch { display: inline-flex; align-items: center; gap: var(--s-3); cursor: pointer; min-height: 44px; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 44px; height: 26px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--surface-3);
  border: 1px solid var(--ring);
  position: relative;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 2px; inset-inline-start: 2px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--fg-muted);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.switch input:checked + .switch-track { background: var(--brand); border-color: var(--brand); }
.switch input:checked + .switch-track::after { background: #fff; transform: translateX(18px); }
[dir="rtl"] .switch input:checked + .switch-track::after { transform: translateX(-18px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--ring-focus); outline-offset: 2px; }

/* Pills */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 38px;
  padding: 0 var(--s-4);
  border: 1px solid var(--ring);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--fg-muted);
  font: inherit;
  font-size: .84rem;
  font-weight: 550;
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--dur-fast) var(--ease);
}
.pill svg { width: 16px; height: 16px; flex: none; }
.pill:hover { background: var(--surface-2); color: var(--fg); border-color: var(--ring-strong); }
.pill[aria-pressed="true"], .pill.is-active {
  background: var(--brand-soft);
  border-color: var(--brand-ring);
  color: var(--fg);
  box-shadow: 0 0 0 1px var(--brand-ring) inset;
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .8; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 3px var(--s-2);
  border-radius: var(--r-full);
  border: 1px solid var(--ring);
  background: var(--surface-2);
  color: var(--fg-muted);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
}
.badge-ok    { background: var(--ok-soft);     color: var(--ok);     border-color: rgba(52,211,153,.25); }
.badge-warn  { background: var(--warn-soft);   color: var(--warn);   border-color: rgba(251,191,36,.25); }
.badge-danger{ background: var(--danger-soft); color: var(--danger); border-color: rgba(251,106,130,.25); }
.badge-brand { background: var(--brand-soft);  color: var(--brand-tint); border-color: var(--brand-ring); }

/* --------------------------------------------------------------------------
   5. Cards & panels
   -------------------------------------------------------------------------- */
.card {
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border: 1px solid var(--ring);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  box-shadow: var(--shadow-md);
}
@media (max-width: 640px) { .card { padding: var(--s-4); border-radius: var(--r-md); } }

.panel {
  background: var(--bg-elevated);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  padding: var(--s-4);
}

/* --------------------------------------------------------------------------
   6. Navbar
   -------------------------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  padding-top: var(--safe-t);
  background: var(--overlay);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  border-bottom: 1px solid var(--ring);
}
.nav-inner {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  height: var(--nav-h);
}
.brand { display: inline-flex; align-items: center; gap: var(--s-3); flex: none; min-height: 44px; }
.brand:hover { color: inherit; }
.brand-logo {
  width: 36px; height: 36px;
  flex: none;
  border-radius: 10px;
  object-fit: cover;
  border: 1px solid var(--ring);
  background: linear-gradient(135deg, var(--brand), var(--accent));
  box-shadow: var(--shadow-sm);
}
.brand-name { font-size: 1.05rem; font-weight: 700; letter-spacing: -.03em; }
.brand-name span { color: var(--brand-text); }

.nav-links { display: flex; align-items: center; gap: var(--s-1); margin-inline-start: var(--s-2); }
.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  font-size: .88rem;
  font-weight: 500;
  color: var(--fg-muted);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav-link:hover { color: var(--fg); background: var(--surface-2); }

.nav-actions { display: flex; align-items: center; gap: var(--s-2); margin-inline-start: auto; }
.nav-socials { display: flex; align-items: center; gap: var(--s-1); }
.nav-socials a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: var(--r-sm);
  color: var(--fg-subtle);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav-socials a:hover { color: var(--fg); background: var(--surface-2); }
.nav-socials svg { width: 18px; height: 18px; }

.lang-wrap { position: relative; }
.lang-menu {
  position: absolute;
  top: calc(100% + 8px);
  inset-inline-end: 0;
  min-width: 200px;
  padding: var(--s-2);
  background: var(--surface);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  z-index: 70;
  animation: pop var(--dur) var(--ease);
}
.lang-menu button {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  min-height: 42px;
  padding: 0 var(--s-3);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--fg-muted);
  font: inherit;
  font-size: .88rem;
  text-align: start;
  cursor: pointer;
}
.lang-menu button:hover { background: var(--surface-2); color: var(--fg); }
.lang-menu button[aria-current="true"] { color: var(--fg); background: var(--brand-soft); }
.lang-menu .flag { font-size: 1.05rem; line-height: 1; }
.lang-menu .native { margin-inline-start: auto; font-size: .76rem; color: var(--fg-subtle); }

@keyframes pop {
  from { opacity: 0; transform: translateY(-6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.nav-toggle { display: none; }
@media (max-width: 980px) {
  .nav-links, .nav-socials { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* Below ~380px the brand plus three action buttons no longer fit inside the
   container padding. Drop the language label to its icon and tighten the
   gaps — every control keeps its 36px+ touch target. */
@media (max-width: 380px) {
  .nav-inner { gap: var(--s-2); }
  .nav-actions { gap: var(--s-1); }
  #lang-btn { width: 40px; padding: 0; }
  #lang-btn span { display: none; }
  .brand-logo { width: 32px; height: 32px; }
  .brand-name { font-size: .96rem; }
}

/* Mobile drawer */
.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(0,0,0,.6);
  backdrop-filter: blur(3px);
  animation: fade var(--dur) var(--ease);
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.drawer {
  position: fixed;
  top: 0;
  inset-inline-end: 0;
  z-index: 91;
  display: flex;
  flex-direction: column;
  width: min(360px, 88vw);
  height: 100dvh;
  padding: calc(var(--safe-t) + var(--s-5)) var(--s-5) calc(var(--safe-b) + var(--s-5));
  background: var(--bg-elevated);
  border-inline-start: 1px solid var(--ring);
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
  animation: slide-in var(--dur-slow) var(--ease);
}
@keyframes slide-in {
  from { transform: translateX(100%); }
  to   { transform: none; }
}
[dir="rtl"] .drawer { animation-name: slide-in-rtl; }
@keyframes slide-in-rtl {
  from { transform: translateX(-100%); }
  to   { transform: none; }
}
.drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-6); }
.drawer nav { display: flex; flex-direction: column; gap: var(--s-1); }
.drawer nav a {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 48px;
  padding: 0 var(--s-3);
  border-radius: var(--r-md);
  color: var(--fg-muted);
  font-weight: 500;
}
.drawer nav a svg { width: 18px; height: 18px; flex: none; }
.drawer nav a:hover { background: var(--surface-2); color: var(--fg); }
.drawer-socials { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: auto; padding-top: var(--s-6); }
.drawer-socials a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  color: var(--fg-muted);
}
.drawer-socials a:hover { color: var(--fg); background: var(--surface-2); }
.drawer-socials svg { width: 19px; height: 19px; }

/* --------------------------------------------------------------------------
   7. Hero + search + category pills
   -------------------------------------------------------------------------- */
.hero { position: relative; z-index: 1; padding: var(--s-16) 0 var(--s-8); text-align: center; }
@media (max-width: 640px) { .hero { padding: var(--s-10) 0 var(--s-6); } }
.hero .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  margin-bottom: var(--s-5);
  border: 1px solid var(--ring);
  border-radius: var(--r-full);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(8px);
  font-size: .8rem;
  color: var(--fg-muted);
}
.hero .eyebrow .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 3px var(--ok-soft);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}
.hero p.lede {
  max-width: 62ch;
  margin-inline: auto;
  font-size: clamp(.98rem, .93rem + .3vw, 1.12rem);
  color: var(--fg-muted);
}
.hero-stats { display: flex; justify-content: center; flex-wrap: wrap; gap: var(--s-6); margin-top: var(--s-6); }
.hero-stats div { text-align: center; }
.hero-stats b { display: block; font-size: 1.3rem; font-weight: 700; letter-spacing: -.03em; }
.hero-stats span { font-size: .76rem; color: var(--fg-subtle); text-transform: uppercase; letter-spacing: .06em; }

.searchbar { position: relative; z-index: 1; max-width: 720px; margin: var(--s-8) auto var(--s-5); }
.searchbar-field { position: relative; display: flex; align-items: center; }
.searchbar-field svg.icon-search {
  position: absolute;
  inset-inline-start: var(--s-4);
  width: 19px; height: 19px;
  color: var(--fg-subtle);
  pointer-events: none;
}
#tool-search {
  min-height: 56px;
  padding-inline: calc(var(--s-4) * 2 + 19px) var(--s-16);
  border-radius: var(--r-xl);
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: blur(12px);
  font-size: 1rem;
  box-shadow: var(--shadow-md);
}
#tool-search:focus { box-shadow: var(--glow); }
.searchbar kbd {
  position: absolute;
  inset-inline-end: var(--s-3);
  padding: 4px 8px;
  border: 1px solid var(--ring);
  border-radius: var(--r-xs);
  background: var(--surface-2);
  color: var(--fg-subtle);
  font-size: .72rem;
  pointer-events: none;
}
@media (max-width: 520px) {
  .searchbar kbd { display: none; }
  #tool-search { padding-inline-end: var(--s-4); }
}

.categories {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--s-2);
  position: relative;
  z-index: 1;
  margin-bottom: var(--s-8);
}
@media (max-width: 640px) {
  .categories {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: calc(var(--s-4) * -1);
    padding-inline: var(--s-4);
    scroll-snap-type: x proximity;
  }
  .categories::-webkit-scrollbar { display: none; }
  .categories .pill { scroll-snap-align: start; }
}

/* --------------------------------------------------------------------------
   8. Tool grid
   -------------------------------------------------------------------------- */
.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--s-4);
  position: relative;
  z-index: 1;
}
@media (max-width: 400px) { .tool-grid { grid-template-columns: 1fr; } }

.tool-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-5);
  border: 1px solid var(--ring);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--surface) 62%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  text-align: start;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tool-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  background: radial-gradient(120% 90% at 50% 0%, var(--brand-soft), transparent 70%);
  transition: opacity var(--dur) var(--ease);
}
.tool-card:hover {
  transform: translateY(-3px);
  border-color: var(--brand-ring);
  box-shadow: var(--shadow-lg);
  color: inherit;
}
.tool-card:hover::after { opacity: 1; }
.tool-card-top { display: flex; align-items: center; gap: var(--s-3); }
.tool-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  flex: none;
  border-radius: var(--r-md);
  border: 1px solid var(--ring);
  background: var(--surface-2);
  color: var(--brand-text);
}
.tool-card:hover .tool-icon { background: var(--brand-soft); border-color: var(--brand-ring); }
.tool-icon svg { width: 20px; height: 20px; }
.tool-card h3 { margin: 0; font-size: .98rem; font-weight: 620; }
.tool-card p { margin: 0; font-size: .84rem; color: var(--fg-muted); line-height: 1.55; }
.tool-card .badge { align-self: flex-start; margin-top: auto; }

.empty-state { padding: var(--s-16) var(--s-4); text-align: center; color: var(--fg-muted); }
.empty-state svg { width: 46px; height: 46px; margin: 0 auto var(--s-4); color: var(--fg-subtle); }

.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); margin-bottom: var(--s-5); }
.section-head h2 { margin: 0; }
.section-head span { font-size: .82rem; color: var(--fg-subtle); }

/* --------------------------------------------------------------------------
   9. Tool view
   -------------------------------------------------------------------------- */
.tool-view { position: relative; z-index: 1; padding-top: var(--s-6); }

.breadcrumb {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2);
  margin-bottom: var(--s-5);
  font-size: .82rem;
  color: var(--fg-subtle);
}
/* WCAG 2.5.8 asks for a 24x24 target on EVERY pointer type, not just touch.
   At .82rem these links computed to 21px tall, and a breadcrumb link is its own
   block rather than a word inside a sentence, so the "inline" exception does
   not cover it. The coarse-pointer block later raises these to 44px. */
.breadcrumb a {
  display: inline-flex;
  align-items: center;
  min-block-size: 24px;
}
.breadcrumb a:hover { color: var(--brand-text); }
.breadcrumb .sep { opacity: .5; }
[dir="rtl"] .breadcrumb .sep { display: inline-block; transform: scaleX(-1); }

.tool-head { display: flex; align-items: flex-start; gap: var(--s-4); margin-bottom: var(--s-6); }
.tool-head .tool-icon { width: 52px; height: 52px; }
.tool-head .tool-icon svg { width: 25px; height: 25px; }
.tool-head h1 { margin-bottom: var(--s-2); font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.1rem); }
.tool-head p { margin: 0; color: var(--fg-muted); max-width: 70ch; }

.tool-canvas { margin-bottom: var(--s-10); }

/* Prerendered static tool pages reserve the canvas box at its measured height
   (baked in as --h-desk / --h-mob by build/generate.js) so the article below
   never moves when the engine mounts the interactive tool. The breakpoint
   matches .split, which collapses to one column at 860px. */
.tool-canvas.is-reserved { min-height: var(--h-mob, 640px); }
@media (min-width: 861px) {
  .tool-canvas.is-reserved { min-height: var(--h-desk, 560px); }
}
.canvas-skeleton {
  height: var(--h-mob, 640px);
  border: 1px solid var(--ring);
  border-radius: var(--r-lg);
  background-image: linear-gradient(100deg,
    var(--surface) 30%, var(--surface-2) 50%, var(--surface) 70%);
  background-size: 220% 100%;
  animation: banner-shimmer 1.4s var(--ease) infinite;
}
@media (min-width: 861px) {
  .canvas-skeleton { height: var(--h-desk, 560px); }
}
@media (prefers-reduced-motion: reduce) {
  .canvas-skeleton { animation: none; }
}

.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } }
.split-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s-4); }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--s-4);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--ring);
}
.toolbar .grow { flex: 1 1 120px; }

/* Dropzone */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: 210px;
  padding: var(--s-8) var(--s-5);
  border: 1.5px dashed var(--ring-strong);
  border-radius: var(--r-lg);
  background: var(--bg-elevated);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.dropzone:hover, .dropzone.is-over { border-color: var(--brand); background: var(--brand-soft); }
.dropzone.is-over { transform: scale(1.01); }
.dropzone svg { width: 38px; height: 38px; color: var(--brand-text); }
.dropzone strong { font-size: .98rem; }
.dropzone small { color: var(--fg-subtle); font-size: .8rem; }

/* Preview shells */
.preview-box {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  padding: var(--s-4);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background:
    repeating-conic-gradient(var(--surface-2) 0 25%, transparent 0 50%) 50%/22px 22px,
    var(--bg-elevated);
  overflow: auto;
}
.preview-box img, .preview-box canvas {
  max-height: 380px;
  width: auto;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-md);
}

/* Stats grid */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--s-3); }
.stat {
  padding: var(--s-4);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  text-align: center;
}
.stat b { display: block; font-size: 1.5rem; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.stat span { font-size: .74rem; color: var(--fg-subtle); text-transform: uppercase; letter-spacing: .05em; }

/* Alert */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--surface-2);
  font-size: .87rem;
  line-height: 1.55;
}
.alert svg { width: 18px; height: 18px; flex: none; margin-top: 2px; }
.alert-ok     { background: var(--ok-soft);     border-color: rgba(52,211,153,.28);  color: var(--ok); }
.alert-warn   { background: var(--warn-soft);   border-color: rgba(251,191,36,.28);  color: var(--warn); }
.alert-danger { background: var(--danger-soft); border-color: rgba(251,106,130,.28); color: var(--danger); }
.alert code { background: rgba(0,0,0,.25); border-color: transparent; color: inherit; }

/* Result output block */
.output {
  position: relative;
  padding: var(--s-4);
  padding-inline-end: var(--s-12);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  font-family: var(--font-mono);
  font-size: .82rem;
  line-height: 1.7;
  word-break: break-all;
  white-space: pre-wrap;
  min-height: 52px;
}
.output .copy-btn { position: absolute; top: var(--s-2); inset-inline-end: var(--s-2); }

.copyable-row {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--ring);
  border-radius: var(--r-sm);
  background: var(--bg-elevated);
  font-family: var(--font-mono);
  font-size: .8rem;
}
.copyable-row .grow { overflow-x: auto; white-space: nowrap; }

/* Toast */
.toasts {
  position: fixed;
  z-index: 200;
  inset-block-end: calc(var(--safe-b) + var(--s-5));
  inset-inline-end: max(var(--s-5), var(--safe-r));
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  font-size: .87rem;
  animation: toast-in var(--dur) var(--ease);
  max-width: min(360px, 86vw);
}
.toast.out { animation: toast-out var(--dur) var(--ease) forwards; }
.toast svg { width: 17px; height: 17px; flex: none; }
.toast-ok svg { color: var(--ok); }
.toast-danger svg { color: var(--danger); }
@keyframes toast-in  { from { opacity: 0; transform: translateY(12px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(8px) scale(.97); } }

/* --------------------------------------------------------------------------
   10. SEO content blocks
   -------------------------------------------------------------------------- */
.seo-section {
  max-width: 78ch;
  margin: var(--s-12) auto 0;
  padding-top: var(--s-10);
  border-top: 1px solid var(--ring);
}
.seo-section h2 { margin-top: var(--s-10); }
.seo-section h2:first-child { margin-top: 0; }
.seo-section h3 { margin-top: var(--s-6); color: var(--fg); }
.seo-section p, .seo-section li { color: var(--fg-muted); font-size: .95rem; }

.steps { list-style: none; counter-reset: step; padding: 0; margin: 0 0 var(--s-4); }
.steps li {
  position: relative;
  counter-increment: step;
  padding-inline-start: var(--s-10);
  margin-bottom: var(--s-4);
}
.steps li::before {
  content: counter(step);
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--brand-soft);
  border: 1px solid var(--brand-ring);
  color: var(--brand-tint);
  font-size: .8rem;
  font-weight: 700;
  font-family: var(--font-mono);
}
.steps li strong { color: var(--fg); }

.faq { display: flex; flex-direction: column; gap: var(--s-2); }
.faq details {
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease);
}
.faq details[open] { border-color: var(--ring-strong); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 56px;
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  font-weight: 560;
  font-size: .93rem;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  width: 9px; height: 9px;
  flex: none;
  border-right: 2px solid var(--fg-subtle);
  border-bottom: 2px solid var(--fg-subtle);
  transform: rotate(45deg);
  transition: transform var(--dur) var(--ease);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover { background: var(--surface-2); }
.faq .faq-body { padding: 0 var(--s-4) var(--s-4); color: var(--fg-muted); font-size: .9rem; }
.faq .faq-body p:last-child { margin-bottom: 0; }

.privacy-note {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  padding: var(--s-5);
  margin: var(--s-8) 0;
  border: 1px solid rgba(52,211,153,.24);
  border-radius: var(--r-lg);
  background: var(--ok-soft);
}
.privacy-note svg { width: 26px; height: 26px; flex: none; color: var(--ok); }
.privacy-note strong { display: block; margin-bottom: var(--s-1); color: var(--fg); }
.privacy-note p { margin: 0; font-size: .88rem; color: var(--fg-muted); }

.related-tools { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-4); }

/* --------------------------------------------------------------------------
   11. Ad slots
   -------------------------------------------------------------------------- */
.ad-slot {
  position: relative;
  z-index: 1;
  margin: var(--s-6) auto;
  padding: var(--s-3);
  border: 1px dashed var(--ring);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--surface) 46%, transparent);
  text-align: center;
  overflow: hidden;
}
.ad-slot:empty, .ad-slot[hidden] { display: none; }
.ad-slot::before {
  content: "Advertisement";
  display: block;
  margin-bottom: var(--s-2);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}

/* Banner creative. width/height attributes are set from the admin-supplied
   intrinsic size, so the browser derives the aspect ratio and reserves the
   box before the bytes arrive — the image scales down responsively without
   ever shifting surrounding content. */
.ad-slot a { display: block; line-height: 0; }
.ad-slot img {
  width: auto;
  height: auto;
  max-width: 100%;
  /* Ceiling so a mis-sized creative cannot take over the page. The browser
     still derives the reserved box from the width/height attributes, so
     constraining it here does not reintroduce a layout shift. */
  max-height: 280px;
  margin-inline: auto;
  border-radius: var(--r-sm);
  object-fit: contain;
}
/* Leaderboards sit above the fold — keep them shallow. */
#ad-header img { max-height: 120px; }
/* Skeleton shimmer held in the reserved box until the creative paints. */
.ad-slot.is-loading {
  background-image: linear-gradient(100deg,
    var(--surface-2) 30%, var(--surface-3) 50%, var(--surface-2) 70%);
  background-size: 220% 100%;
  animation: banner-shimmer 1.4s var(--ease) infinite;
}
.ad-slot.is-loading img { opacity: 0; }
.ad-slot img { transition: opacity var(--dur) var(--ease); }
@keyframes banner-shimmer {
  from { background-position: 180% 0; }
  to   { background-position: -40% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ad-slot.is-loading { animation: none; }
}

#ad-header { margin-top: var(--s-4); margin-bottom: 0; }

/* --------------------------------------------------------------------------
   12. Footer
   -------------------------------------------------------------------------- */
.footer {
  position: relative;
  z-index: 1;
  margin-top: var(--s-20);
  padding: var(--s-12) 0 calc(var(--s-8) + var(--safe-b));
  border-top: 1px solid var(--ring);
  background: var(--bg-elevated);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: var(--s-8);
  margin-bottom: var(--s-10);
}
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--s-6); } }
@media (max-width: 540px) { .footer-grid { grid-template-columns: 1fr; } }
.footer h4 {
  margin-bottom: var(--s-4);
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--fg-subtle);
  font-weight: 650;
}
.footer ul { list-style: none; padding: 0; margin: 0; }
/* The list gap is folded into the links themselves so each one is a full
   44px touch target without leaving dead space between them. */
.footer li { margin-bottom: 0; }
.footer li a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-inline-end: var(--s-2);
}
.footer a { font-size: .88rem; color: var(--fg-muted); }
.footer a:hover { color: var(--brand-text); }
.footer-brand p { margin-top: var(--s-4); font-size: .87rem; color: var(--fg-muted); max-width: 40ch; }
.footer-socials { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-5); }
.footer-socials a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  color: var(--fg-muted);
  transition: all var(--dur-fast) var(--ease);
}
.footer-socials a:hover { color: var(--fg); background: var(--surface-2); border-color: var(--ring-strong); transform: translateY(-2px); }
.footer-socials svg { width: 18px; height: 18px; }
.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-3);
  padding-top: var(--s-6);
  border-top: 1px solid var(--ring);
  font-size: .82rem;
  color: var(--fg-subtle);
}

/* --------------------------------------------------------------------------
   13. Tool-specific pieces
   -------------------------------------------------------------------------- */
/* Palette swatches */
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: var(--s-3); }
.swatch {
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  overflow: hidden;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.swatch:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.swatch-color { height: 76px; }
.swatch-meta { padding: var(--s-2) var(--s-3); background: var(--bg-elevated); font-family: var(--font-mono); font-size: .76rem; }
.swatch-meta span { display: block; color: var(--fg-subtle); font-size: .7rem; }

/* Diff output */
.diff-pane {
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  font-family: var(--font-mono);
  font-size: .8rem;
  line-height: 1.75;
  overflow: auto;
  max-height: 520px;
}
.diff-line { display: flex; gap: var(--s-3); padding: 0 var(--s-3); white-space: pre-wrap; word-break: break-word; }
.diff-line .ln { flex: none; width: 3ch; text-align: end; color: var(--fg-subtle); user-select: none; }
.diff-add { background: rgba(52,211,153,.13); color: #6ee7b7; }
.diff-del { background: rgba(251,106,130,.13); color: #fca5a5; }
.diff-same { color: var(--fg-muted); }
.diff-empty { background: color-mix(in srgb, var(--surface-2) 60%, transparent); min-height: 1.75em; }
mark.d-add { background: rgba(52,211,153,.3); color: #d1fae5; border-radius: 3px; }
mark.d-del { background: rgba(251,106,130,.3); color: #fee2e2; border-radius: 3px; text-decoration: line-through; }

/* Markdown preview */
.md-preview {
  padding: var(--s-5);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  min-height: 320px;
  max-height: 620px;
  overflow: auto;
}
.md-preview > :first-child { margin-top: 0; }
.md-preview h1, .md-preview h2 { padding-bottom: var(--s-2); border-bottom: 1px solid var(--ring); }
.md-preview h1, .md-preview h2, .md-preview h3, .md-preview h4 { margin-top: var(--s-6); }
.md-preview blockquote {
  margin: 0 0 var(--s-4);
  padding: var(--s-1) var(--s-4);
  border-inline-start: 3px solid var(--brand);
  color: var(--fg-muted);
}
.md-preview table { width: 100%; border-collapse: collapse; margin-bottom: var(--s-4); font-size: .88rem; }
.md-preview th, .md-preview td { padding: var(--s-2) var(--s-3); border: 1px solid var(--ring); text-align: start; }
.md-preview th { background: var(--surface-2); font-weight: 600; }
.md-preview img { border-radius: var(--r-sm); }
.md-preview hr { margin: var(--s-6) 0; }
.md-preview ul.task-list { list-style: none; padding-inline-start: 0; }

/* Password strength meter */
.meter { height: 8px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.meter i { display: block; height: 100%; width: 0; border-radius: var(--r-full); transition: width var(--dur) var(--ease), background var(--dur) var(--ease); }

/* QR output */
.qr-stage {
  display: grid;
  place-items: center;
  padding: var(--s-6);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  min-height: 300px;
}
.qr-stage svg { width: min(280px, 70vw); height: auto; border-radius: var(--r-sm); }

/* Crop overlay */
.crop-stage { position: relative; display: inline-block; max-width: 100%; touch-action: none; }
.crop-stage img { display: block; max-width: 100%; user-select: none; -webkit-user-drag: none; }
.crop-box {
  position: absolute;
  border: 2px solid var(--brand);
  box-shadow: 0 0 0 9999px rgba(9,9,11,.62);
  cursor: move;
}
.crop-handle {
  position: absolute;
  width: 16px; height: 16px;
  background: #fff;
  border: 2px solid var(--brand);
  border-radius: 3px;
  right: -9px; bottom: -9px;
  cursor: nwse-resize;
}

/* Timestamp clock */
.epoch-clock {
  font-family: var(--font-mono);
  font-size: clamp(1.8rem, 1.2rem + 3.4vw, 3rem);
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--brand-text);
  text-align: center;
  direction: ltr;
}

/* Table */
.table-wrap { overflow-x: auto; border: 1px solid var(--ring); border-radius: var(--r-md); }
table.data { width: 100%; border-collapse: collapse; font-size: .87rem; }
table.data th, table.data td { padding: var(--s-3) var(--s-4); text-align: start; border-bottom: 1px solid var(--ring); }
table.data th {
  background: var(--surface-2);
  font-weight: 600;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--fg-subtle);
  white-space: nowrap;
}
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data td.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.bar { height: 6px; border-radius: var(--r-full); background: linear-gradient(90deg, var(--brand), var(--accent)); min-width: 3px; }

/* --------------------------------------------------------------------------
   14. RTL adjustments
   -------------------------------------------------------------------------- */
[dir="rtl"] { letter-spacing: 0; }
[dir="rtl"] .searchbar-field svg.icon-search { transform: scaleX(-1); }
[dir="rtl"] .mono, [dir="rtl"] .output, [dir="rtl"] .textarea,
[dir="rtl"] .copyable-row, [dir="rtl"] .diff-pane { direction: ltr; text-align: start; }
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3 { letter-spacing: 0; }

/* --------------------------------------------------------------------------
   15b. File queue (PDF tools)
   A reorderable list of picked files. Rows are sized so the move/remove
   controls keep a comfortable hit area without the list dominating the card.
   -------------------------------------------------------------------------- */
.file-queue {
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.file-queue:empty { margin: 0; }

.file-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3);
  border: 1px solid var(--ring);
  border-radius: var(--r-md);
  background: var(--surface-2);
}

.file-index {
  flex: 0 0 auto;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--surface-3);
  color: var(--fg-subtle);
  font-size: .78rem;
  font-variant-numeric: tabular-nums;
}

.file-meta {
  flex: 1 1 auto;
  min-inline-size: 0;           /* lets a long filename ellipsize, not overflow */
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.file-meta strong {
  font-size: .9rem;
  font-weight: 550;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.file-meta small { color: var(--fg-subtle); font-size: .78rem; }

.file-actions { flex: 0 0 auto; display: flex; gap: var(--s-2); }
.file-actions .btn[disabled] { opacity: .35; }

/* Indeterminate work indicator — CSS-only, no layout impact. */
.spinner {
  inline-size: 1rem;
  block-size: 1rem;
  flex: 0 0 auto;
  border: 2px solid var(--ring);
  border-top-color: var(--brand);
  border-radius: var(--r-full);
  animation: jt-spin .7s linear infinite;
}
@keyframes jt-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.4s; }
}

/* --------------------------------------------------------------------------
   16. Touch targets
   Placed last so these win on source order. Coarse pointers (phones, tablets)
   get a full 44x44 hit area on every compact control; mouse users keep the
   denser 36/38px sizing that suits a cursor.
   -------------------------------------------------------------------------- */
@media (pointer: coarse) {
  .btn-sm,
  .btn-icon.btn-sm { min-height: 44px; }
  /* Icon-only .btn-sm buttons land at 42–43px from padding alone. */
  .btn-sm { min-width: 44px; }
  .btn-icon.btn-sm { width: 44px; }
  .pill { min-height: 44px; }
  .check { min-height: 44px; }
  .nav-actions .btn,
  #lang-btn,
  #theme-toggle,
  #drawer-open { min-height: 44px; }
  #lang-btn,
  #theme-toggle,
  #drawer-open { width: 44px; }
  .swatch { min-height: 44px; }
  .faq summary { min-height: 56px; }
  .breadcrumb a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
    padding-inline: var(--s-2);
  }
  .breadcrumb { margin-bottom: var(--s-3); }
}

/* --------------------------------------------------------------------------
   15. Print
   -------------------------------------------------------------------------- */
@media print {
  .nav, .footer, .ad-slot, .searchbar, .categories, .toasts { display: none !important; }
  body { background: #fff; color: #000; }
  body::before { display: none; }
}
