/* Trendy AI Lab - web design system.
   Source of truth: design-system/trendy-ai-lab-web/MASTER.md (carries the contrast table).

   Tokens only below this block: a raw hex in a rule cannot be themed, which is exactly what
   left tools.css untheme-able. Light is the base; dark wins by OS preference or by the
   explicit toggle. Every foreground/background pair here was computed against WCAG rather
   than eyeballed, and the two themes were checked separately - dark is a designed
   counterpart, never an inversion. */

:root {
      color-scheme: light;

      /* -- Brand fills. Identical in both themes: decorative, never text. -- */
      --violet:#8B5CFF; --cyan:#22D3EE; --magenta:#FF4FD8; --credit:#FFC857; --danger:#FB6F84;
      /* Text placed ON a brand fill. Near-black in BOTH themes, never white: white on
         violet is 4.14:1 and fails. Mirrors AppColors.textOnAccent in the app. */
      --ink:#0B0712; --on-accent:#0B0712;
      --grad:linear-gradient(135deg,#FF4FD8 0%,#8B5CFF 52%,#22D3EE 100%);
      --grad-brand:linear-gradient(135deg,#8B5CFF,#22D3EE);

      /* -- Type. Two families, referenced only through these tokens. --
         Bricolage Grotesque (display) is a variable grotesque with a real voice and an
         optical-size axis; Instrument Sans (text) is a quiet workhorse that holds up at
         14-16px in the tools UI. Deliberately NOT Plus Jakarta Sans / Inter, nor the
         usual substitutes (Space Grotesk, DM Sans, Poppins, Manrope, Playfair Display):
         those pairings are the ones that make a site read as machine-assembled. */
      --font-display:"Bricolage Grotesque","Trebuchet MS",sans-serif;
      --font-text:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;

      /* -- Layout + scale (theme-independent) -- */
      --maxw:1120px; --gutter:22px;
      --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
      --space-5:24px; --space-6:32px; --space-7:48px; --space-8:64px;
      --radius-sm:8px; --radius-md:12px; --radius-lg:18px; --radius-pill:999px;

      /* -- Light surfaces + text -- */
      --bg:#FAF7FF; --bg2:#F3EEFB; --surface:#FFFFFF; --surface-2:#F7F4FD; --surface-top:#EFEAF9;
      --text:#1A1523; --text-strong:#0E0A16; --muted:#5B5570; --faint:#6E6785;
      --line:rgba(26,21,35,.10); --line-strong:rgba(26,21,35,.18);
      --edge:rgba(26,21,35,.10); --edge-2:rgba(26,21,35,.14); --edge-hover:rgba(26,21,35,.28);
      --glass:rgba(26,21,35,.04); --neon:rgba(139,92,255,.20);
      /* Overlay/shadow channels. Alpha overlays are hardcoded white in a dark-only
         stylesheet, which turns invisible on light; flipping the channel keeps every
         existing alpha value intact instead of re-picking 52 colours by hand. */
      --fg-rgb:26,21,35; --shadow-rgb:26,21,35;
      /* Translucent nav and the page's ambient wash: baked to the dark look, so both
         need a light counterpart or the chrome floats dark over a light page. */
      --nav-bg:rgba(250,247,255,.82); --nav-bg-solid:rgba(250,247,255,.98);
      /* Translucent card surfaces (tools.css). A surface hex written straight into
         rgba() cannot follow a theme, so it gets its own token. */
      --surface-glass:rgba(255,255,255,.70); --surface-2-glass:rgba(247,244,253,.92);
      /* Per-tool identity colours are used as TEXT, not just as fills, and every one of
         them fails on a light card (2.07-3.99:1). These are the mix parameters only: the
         mix itself has to happen on the element that carries --tool-accent, because a
         var() inside a custom property resolves in the scope where it is DECLARED, so a
         :root definition would silently give every tool the same fallback colour. */
      --tool-mix-pct:62%; --tool-mix-with:black;
      --wash:rgba(233,224,250,.75);
      /* Brand hues as TEXT on light: the raw fills fail (violet 3.91, cyan 1.71, gold 1.45,
         danger 2.57), so each carries a darker tonal variant that clears 4.5:1. */
      --violet-text:#6D28D9; --cyan-text:#0E7490; --credit-text:#8A6100; --danger-text:#C0293F;
      /* A violet glow is invisible on light, so elevation reads as a neutral shadow. */
      --glow:0 8px 24px rgba(26,21,35,.10); --glow-sm:0 4px 14px rgba(26,21,35,.08);
      --shadow-md:0 8px 24px rgba(26,21,35,.10);
      --shadow-menu:0 24px 60px rgba(26,21,35,.16), 0 0 40px rgba(139,92,255,.10);
      /* A specular top highlight, not an ink overlay: stays white in both themes. */
      --shadow-chip:0 4px 14px rgba(26,21,35,.10), inset 0 1px 0 rgba(255,255,255,.9);
      --shadow-chip-hover:0 6px 20px rgba(26,21,35,.16), 0 0 14px rgba(139,92,255,.12);
      --grad-chip:linear-gradient(135deg,#FFFFFF 0%,#F3EEFB 100%);
      --grad-chip-hover:linear-gradient(135deg,#F7F4FD 0%,#EFEAF9 100%);
      /* Ink on the cover-card scrim. The scrim is a dark gradient over a photo in both
         themes, so this one stays white rather than following the theme. */
      --on-scrim:#FFFFFF;
}

/* The two dark blocks below MUST declare the same tokens: one covers "the OS says dark and
   the visitor has not overridden it", the other the explicit toggle. CSS cannot share a
   declaration block across a media query, so they are duplicated - and guarded by
   test_dark_theme_blocks_declare_the_same_tokens. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
      color-scheme: dark;
      --bg:#0E0E14; --bg2:#14141C; --surface:#1A1A24; --surface-2:#22222E; --surface-top:#2A2A38;
      --text:#F5F5FA; --text-strong:#FFFFFF; --muted:#9A9AB0; --faint:#7E7E92;
      --line:rgba(var(--fg-rgb),.12); --line-strong:rgba(var(--fg-rgb),.20);
      --edge:rgba(var(--fg-rgb),.14); --edge-2:rgba(var(--fg-rgb),.16); --edge-hover:rgba(var(--fg-rgb),.32);
      --glass:rgba(var(--fg-rgb),.06); --neon:rgba(139,92,255,.28);
      --fg-rgb:255,255,255; --shadow-rgb:0,0,0;
      --nav-bg:rgba(11,7,18,.75); --nav-bg-solid:rgba(11,7,18,.98);
      --surface-glass:rgba(26,26,36,.70); --surface-2-glass:rgba(34,34,48,.92);
      --tool-mix-pct:79%; --tool-mix-with:white;
      --wash:rgba(28,20,54,.95);
      --violet-text:#8B5CFF; --cyan-text:#22D3EE; --credit-text:#FFC857; --danger-text:#FB6F84;
      --glow:0 10px 30px rgba(139,92,255,.35); --glow-sm:0 6px 20px rgba(139,92,255,.20);
      --shadow-md:0 8px 24px rgba(var(--shadow-rgb),.3);
      --shadow-menu:0 24px 60px rgba(var(--shadow-rgb),.75), 0 0 40px rgba(139,92,255,.18);
      --shadow-chip:0 4px 14px rgba(var(--shadow-rgb),.35), inset 0 1px 0 rgba(var(--fg-rgb),.12);
      --shadow-chip-hover:0 6px 20px rgba(var(--shadow-rgb),.45), 0 0 14px rgba(var(--fg-rgb),.08);
      --grad-chip:linear-gradient(135deg,#2D2D3D 0%,#1E1E2A 100%);
      --grad-chip-hover:linear-gradient(135deg,#3A3A4E 0%,#262636 100%);
      /* Ink on the cover-card scrim. The scrim is a dark gradient over a photo in both
         themes, so this one stays white rather than following the theme. */
      --on-scrim:#FFFFFF;
  }
}
:root[data-theme="dark"] {
      color-scheme: dark;
      --bg:#0E0E14; --bg2:#14141C; --surface:#1A1A24; --surface-2:#22222E; --surface-top:#2A2A38;
      --text:#F5F5FA; --text-strong:#FFFFFF; --muted:#9A9AB0; --faint:#7E7E92;
      --line:rgba(var(--fg-rgb),.12); --line-strong:rgba(var(--fg-rgb),.20);
      --edge:rgba(var(--fg-rgb),.14); --edge-2:rgba(var(--fg-rgb),.16); --edge-hover:rgba(var(--fg-rgb),.32);
      --glass:rgba(var(--fg-rgb),.06); --neon:rgba(139,92,255,.28);
      --fg-rgb:255,255,255; --shadow-rgb:0,0,0;
      --nav-bg:rgba(11,7,18,.75); --nav-bg-solid:rgba(11,7,18,.98);
      --surface-glass:rgba(26,26,36,.70); --surface-2-glass:rgba(34,34,48,.92);
      --tool-mix-pct:79%; --tool-mix-with:white;
      --wash:rgba(28,20,54,.95);
      --violet-text:#8B5CFF; --cyan-text:#22D3EE; --credit-text:#FFC857; --danger-text:#FB6F84;
      --glow:0 10px 30px rgba(139,92,255,.35); --glow-sm:0 6px 20px rgba(139,92,255,.20);
      --shadow-md:0 8px 24px rgba(var(--shadow-rgb),.3);
      --shadow-menu:0 24px 60px rgba(var(--shadow-rgb),.75), 0 0 40px rgba(139,92,255,.18);
      --shadow-chip:0 4px 14px rgba(var(--shadow-rgb),.35), inset 0 1px 0 rgba(var(--fg-rgb),.12);
      --shadow-chip-hover:0 6px 20px rgba(var(--shadow-rgb),.45), 0 0 14px rgba(var(--fg-rgb),.08);
      --grad-chip:linear-gradient(135deg,#2D2D3D 0%,#1E1E2A 100%);
      --grad-chip-hover:linear-gradient(135deg,#3A3A4E 0%,#262636 100%);
      /* Ink on the cover-card scrim. The scrim is a dark gradient over a photo in both
         themes, so this one stays white rather than following the theme. */
      --on-scrim:#FFFFFF;
}

    * { box-sizing:border-box; }
    html { scroll-behavior:smooth; }
    body {
      margin:0; background:var(--bg); color:var(--text); overflow-x:hidden;
      font-family:var(--font-text);
      line-height:1.65; -webkit-font-smoothing:antialiased;
      background-image:
        radial-gradient(60rem 45rem at 50% -14%, var(--wash), transparent 62%),
        radial-gradient(46rem 38rem at 88% 2%, rgba(139,92,255,.14), transparent 55%),
        radial-gradient(42rem 36rem at 2% 10%, rgba(34,211,238,.10), transparent 55%),
        radial-gradient(40rem 34rem at 96% 60%, rgba(255,79,216,.07), transparent 55%);
      background-repeat:no-repeat;
    }
    img { max-width:100%; }

    /* Collection "every style" list. Two columns from 760px: 31 single-column text cards
       ran 5,815px, about half the page, and buried the FAQ and CTA below it. The thumbnail
       is the same example the tile above uses, so the list is scannable by picture too. */
    .style-notes { display:grid; grid-template-columns:repeat(auto-fill,minmax(330px,1fr));
      gap:12px; max-width:var(--maxw); margin:18px auto 0; }
    .style-note { display:flex; gap:12px; align-items:flex-start; background:var(--surface);
      border:1px solid var(--line); border-radius:var(--radius-md); padding:14px 16px; }
    .style-note-thumb { width:56px; height:56px; border-radius:10px; object-fit:cover;
      flex-shrink:0; background:var(--surface-2); }
    .style-note-body { min-width:0; }
    .style-note h3 { margin:0 0 4px; font-size:1.02rem; line-height:1.3; }
    /* The title is a link and has to look like one: it was body-coloured with no underline,
       so nothing signalled it was clickable. */
    .style-note h3 a { color:var(--violet-text); text-decoration:none; }
    .style-note h3 a:hover, .style-note h3 a:focus-visible { text-decoration:underline; }
    .style-note p { margin:0; color:var(--muted); font-size:.92rem; line-height:1.5; }
    .style-note-detail { margin-top:5px !important; color:var(--faint) !important; font-size:.86rem !important; }
    @media (max-width:680px) {
      .style-notes { grid-template-columns:1fr; }
      .style-note { padding:12px 13px; }
    }

    h1,h2,h3 { font-family:var(--font-display); line-height:1.15; letter-spacing:-.02em; overflow-wrap:break-word; }
    a { color:var(--violet); text-decoration:none; }
    a:hover { text-decoration:underline; }
    .wrap { max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter); }
    .grad-text { background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent; }

    /* Nav */
    .nav {
      position:sticky; top:0; z-index:100; backdrop-filter:blur(12px);
      background:var(--nav-bg); border-bottom:1px solid var(--line);
    }
    /* Three zones: brand left, nav centred in the viewport, theme toggle right. The
       1fr/auto/1fr grid centres the middle column against the container rather than
       against the space the brand leaves over, which a flex row cannot do. Columns are
       placed explicitly because under 1100px `.links` goes `position:absolute` and
       auto-placement would then slide the actions group into the middle column. The
       brand is left to auto-place into column 1 so it keeps a single `.brand` rule. */
    .nav-inner { display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
      gap:20px; min-height:76px; position:relative; }
    .nav .links { grid-column:2; }
    .nav-actions { grid-column:3; justify-self:end; display:flex; align-items:center; gap:10px; }
    .brand { display:flex; align-items:center; gap:12px; font-family:var(--font-display); font-weight:800;
      color:var(--text); font-size:1.15rem; flex-shrink:0; min-height:44px; }
    .brand:hover { text-decoration:none; }
    .brand .logo { width:44px; height:44px; border-radius:12px; display:block; box-shadow:var(--glow-sm); }
    .brand .brand-mark { display:flex; flex-direction:column; align-items:flex-start; line-height:1; gap:4px; flex-shrink:0; }
    .brand .brand-mark .wordmark { font-family:var(--font-display); font-weight:800; font-size:1.25rem; letter-spacing:-.01em; white-space:nowrap; }
    .brand .brand-mark .tagline { font-family:var(--font-display); font-weight:700; font-size:.66rem; letter-spacing:.22em; color:var(--muted); text-transform:uppercase; white-space:nowrap; }
    .nav a.link { color:var(--muted); font-weight:500; font-size:.95rem; white-space:nowrap; }
    .nav a.link:hover { color:var(--text); text-decoration:none; }
    .nav .links { display:flex; gap:10px; align-items:center; justify-content:center; }

    /* Nav items: AI Styles dropdown & Tools button */
    .nav-dropdown { position:static; display:inline-flex; align-items:center; }
    .nav-btn-link, .nav-tools-btn {
      display:inline-flex; align-items:center; gap:6px; font-family:var(--font-display);
      font-weight:600; font-size:.95rem; color:var(--muted); background:transparent;
      min-height:44px;
      border:1px solid transparent; padding:9px 15px; border-radius:12px; cursor:pointer;
      transition:all .15s ease; text-decoration:none; white-space:nowrap;
    }
    .nav-btn-link:hover, .nav-btn-link:focus, .nav-dropdown:hover .nav-btn-link, .nav-dropdown.is-open .nav-btn-link,
    .nav-tools-btn:hover {
      color:var(--text); background:var(--glass); border-color:var(--line); text-decoration:none;
    }
    .nav-dropdown-chevron {
      display:inline-block; transition:transform .2s ease; opacity:.75;
    }
    .nav-dropdown:hover .nav-dropdown-chevron,
    .nav-dropdown.is-open .nav-dropdown-chevron {
      transform:rotate(180deg);
    }

    /* AI Styles Hover Mega Menu - Dark theme matching Trendy AI Lab */
    .mega-menu-wrapper {
      position:absolute; top:100%; left:0; right:0;
      padding:4px 0 20px;
      pointer-events:none; opacity:0; visibility:hidden;
      transform:translateY(4px);
      transition:opacity .15s cubic-bezier(0.16, 1, 0.3, 1), transform .15s cubic-bezier(0.16, 1, 0.3, 1), visibility .15s cubic-bezier(0.16, 1, 0.3, 1);
      z-index:110;
    }
    /* Seamless hover bridge so cursor never leaves hover zone between button and card */
    .mega-menu-wrapper::before {
      content:""; position:absolute; top:-30px; left:0; right:0; height:34px;
    }
    .nav-dropdown:hover .mega-menu-wrapper,
    .nav-dropdown:focus-within .mega-menu-wrapper,
    .nav-dropdown.is-open .mega-menu-wrapper {
      pointer-events:auto; opacity:1; visibility:visible;
      transform:translateY(0);
    }
    .mega-menu-card {
      background:var(--bg2); color:var(--text);
      border-radius:18px; padding:18px 22px;
      box-shadow:var(--shadow-menu);
      border:1px solid var(--edge);
      backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);
    }
    /* 5 Columns x 5 Rows (Column-major order) */
    .mega-menu-grid {
      display:grid;
      grid-template-rows:repeat(5, auto);
      grid-auto-flow:column;
      grid-template-columns:repeat(5, minmax(0, 1fr));
      gap:4px 12px;
    }
    .mega-cat-item {
      display:flex; align-items:center; gap:8px; padding:6px 9px;
      border-radius:8px; font-size:.88rem; font-weight:500; color:var(--text);
      text-decoration:none; line-height:1.3; min-height:44px;
      transition:background .15s ease, color .15s ease, transform .15s ease;
    }
    .mega-cat-emoji {
      font-size:1rem; line-height:1; display:inline-flex; align-items:center; justify-content:center;
      width:18px; height:18px; flex-shrink:0;
    }
    .mega-cat-icon {
      width:18px; height:18px; object-fit:contain; border-radius:4px; flex-shrink:0;
    }
    .mega-cat-item:hover {
      color:var(--text-strong); background:rgba(139,92,255,.22); text-decoration:none;
      transform:translateX(2px);
    }
    .mega-cat-item.is-active {
      color:var(--text-strong); background:rgba(139,92,255,.32); font-weight:700;
    }
    .mega-cat-item.is-active::before {
      content:""; width:6px; height:6px; border-radius:50%;
      background:var(--cyan); box-shadow:0 0 8px var(--cyan); flex-shrink:0;
    }
    .mega-cat-name {
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
    }
    .mega-see-all-btn {
      display:inline-flex !important; align-items:center !important; justify-content:space-between !important;
      gap:8px !important; padding:6px 12px !important;
      border-radius:9px !important; font-size:.88rem !important; font-weight:700 !important;
      font-family:var(--font-display) !important;
      color:var(--text) !important; text-decoration:none !important; line-height:1.3 !important;
      background:var(--grad-chip) !important;
      border:1px solid var(--edge-2) !important;
      box-shadow:var(--shadow-chip) !important;
      transition:all .18s ease !important;
    }
    .mega-see-all-btn svg {
      transition:transform .18s ease !important; color:var(--muted) !important; flex-shrink:0 !important;
    }
    .mega-see-all-btn:hover {
      background:var(--grad-chip-hover) !important;
      color:var(--text-strong) !important;
      border-color:var(--edge-hover) !important;
      box-shadow:var(--shadow-chip-hover) !important;
      transform:translateX(2px) !important;
      text-decoration:none !important;
    }
    .mega-see-all-btn:hover svg {
      transform:translateX(3px) !important; color:var(--text-strong) !important;
    }

    /* Tools Mega Dropdown Menu - Clean Direct Grid with Icon Badges */
    .tools-mega-card {
      background: var(--bg2);
      color: var(--text);
      border-radius: 18px;
      padding: 18px 22px;
      box-shadow: var(--shadow-menu);
      border: 1px solid var(--edge);
      backdrop-filter: blur(20px);
      -webkit-backdrop-filter: blur(20px);
    }
    .tools-mega-grid {
      display: grid;
      grid-template-rows: repeat(4, auto);
      grid-auto-flow: column;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: 4px 12px;
    }
    .nav-tool-item {
      display: flex;
      align-items: center;
      gap: 9px;
      padding: 9px 8px;
      min-height: 44px;
      border-radius: 9px;
      color: var(--text);
      text-decoration: none;
      transition: all .15s ease;
      position: relative;
    }
    .nav-tool-item:hover {
      background: rgba(var(--fg-rgb), 0.07);
      text-decoration: none;
      transform: translateX(3px);
    }
    .nav-tool-item.is-active {
      background: rgba(139, 92, 255, 0.22);
    }
    .nav-tool-icon-box {
      width: 28px;
      height: 28px;
      min-width: 28px;
      border-radius: 8px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      background: var(--tool-bg, rgba(139,92,255,.15));
      color: var(--tool-color, #8B5CFF);
      border: 1px solid var(--tool-border, rgba(139,92,255,.3));
      transition: all .18s ease;
      flex-shrink: 0;
    }
    .nav-tool-icon-box svg {
      width: 15px;
      height: 15px;
      stroke-width: 2.2;
    }
    .nav-tool-item:hover .nav-tool-icon-box {
      transform: scale(1.08);
      box-shadow: 0 0 12px var(--tool-glow, rgba(139,92,255,.4));
      background: var(--tool-glow, rgba(139,92,255,.25));
    }
    .nav-tool-name {
      font-size: 0.88rem;
      font-weight: 500;
      color: var(--text);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      line-height: 1.3;
    }
    .nav-tool-item:hover .nav-tool-name {
      color: var(--text-strong);
      font-weight: 600;
    }


    /* CSS-only hamburger (checkbox hack, no JS dependency) */
    .nav-toggle { display:none; }
    .nav-burger { display:none; width:44px; height:44px; border-radius:12px; border:1px solid var(--line);
      background:var(--surface); cursor:pointer; align-items:center; justify-content:center; }
    .nav-burger span, .nav-burger span::before, .nav-burger span::after {
      content:""; display:block; width:20px; height:2px; border-radius:2px; background:var(--text); position:relative; }
    .nav-burger span::before { position:absolute; top:-6px; }
    .nav-burger span::after { position:absolute; top:6px; }
    .btn {
      display:inline-flex; align-items:center; gap:8px; font-weight:700; font-family:var(--font-display);
      border-radius:12px; padding:11px 18px; cursor:pointer; border:1px solid transparent; font-size:.95rem;
      transition:transform .15s ease, box-shadow .15s ease, background .15s ease;
    }
    .btn:hover { text-decoration:none; transform:translateY(-1px); }
    .btn-primary { background:var(--grad); color:var(--ink); box-shadow:var(--glow); }
    .btn-primary:hover { box-shadow:0 14px 40px rgba(139,92,255,.5); }
    .btn-ghost { background:var(--glass); color:var(--text); border-color:var(--line); backdrop-filter:blur(8px); }
    .btn-ghost:hover { border-color:var(--neon); box-shadow:var(--glow-sm); }
    .btn-sm { padding:8px 14px; font-size:.9rem; }

    /* Header link to /app. A plain nav link, not a button: the store badge belongs on a
       page we own, and the site leads with the browser tools rather than the install.
       It reads as the third peer of the two dropdowns, so it takes their exact type,
       colour and padding rather than a weight of its own. */
    .nav-cta { display:inline-flex; align-items:center; flex-shrink:0; white-space:nowrap;
      font-family:var(--font-display); font-weight:600; font-size:.95rem; color:var(--muted);
      min-height:44px; padding:9px 15px; border:1px solid transparent; border-radius:12px;
      transition:all .15s ease; }
    .nav-cta:hover, .nav-cta:focus-visible {
      color:var(--text); background:var(--glass); border-color:var(--line); text-decoration:none;
    }

    /* Native app-store badges (official artwork). Global so every page styles them. */
    .store-badges { display:flex; gap:14px; justify-content:center; flex-wrap:wrap; align-items:flex-start; margin-top:30px; }
    .store-badge { display:inline-flex; flex-direction:column; align-items:center; gap:4px; }
    .store-badge img { height:54px; width:auto; display:block; }
    a.store-badge { transition:transform .15s ease, filter .15s ease; }
    a.store-badge:hover { transform:translateY(-2px); text-decoration:none; }
    .store-badge.is-soon img { filter:grayscale(1); opacity:.55; }
    .store-badge.is-soon small { color:var(--muted); font-size:.7rem; letter-spacing:.06em; text-transform:uppercase; }
    .store-rating { margin:12px 0 0; text-align:center; font-size:.92rem; color:var(--muted); }
    .store-rating a { color:inherit; }
    .store-rating strong { color:var(--text); }
    .store-rating-stars { color:var(--credit); letter-spacing:.06em; margin-right:6px; }

    footer { border-top:1px solid var(--line); margin-top:80px; background:var(--bg2); }
    /* Column footer. The brand sits in the first track with the blurb under it, then
       Product / Company / Legal / Get the app. Grid rather than the old flex row so the
       columns line up on their own baseline at every width. */
    .foot { display:grid; grid-template-columns:1.7fr 1fr 1fr 1.15fr 1.2fr; gap:28px 32px;
      align-items:start; padding-top:48px; padding-bottom:36px; }
    /* Restore the brand's flex row, the generic `.foot a` rule below would
       otherwise blockify this anchor, stacking the logo above the wordmark. */
    .foot .brand { display:flex; align-items:center; margin-right:0; padding:0; }
    .foot .brand .logo { width:40px; height:40px; }
    .foot .brand .brand-mark .wordmark { font-size:1.1rem; }
    .foot .brand .brand-mark .tagline { font-size:.6rem; }
    .foot-blurb { color:var(--muted); font-size:.9rem; line-height:1.55;
      margin:14px 0 0; max-width:38ch; }
    .foot-col { display:flex; flex-direction:column; align-items:stretch; }
    .foot-col .foot-h { color:var(--text); font-family:var(--font-display); font-weight:700;
      font-size:.88rem; letter-spacing:.04em; margin-bottom:6px; }
    /* Full-width hit areas, which is also what gets these past WCAG 2.5.8: as an inline
       row these links measured 29-41px wide while passing a height-only 44px check. */
    .foot a { color:var(--muted); font-size:.9rem; display:flex; align-items:center;
      min-height:44px; padding:2px 0; }
    .foot a:hover { color:var(--text); }
    .foot-app .store-badges { justify-content:flex-start; margin-top:8px; gap:10px; }
    .foot-app .store-badge img { height:42px; }
    .foot .copy { grid-column:1 / -1; color:var(--muted); font-size:.85rem;
      border-top:1px solid var(--line); padding-top:22px; }

    /* Breadcrumbs */
    .crumbs { padding-top:22px; font-size:.88rem; color:var(--muted); }
    /* Breadcrumbs sit in a <nav>, so WCAG 2.5.8's inline-text exception does not apply
       to them, the same call the footer links got. inline-flex keeps the trail on one
       line while giving each link a full 44px hit area. */
    .crumbs a { color:var(--muted); display:inline-flex; align-items:center; min-height:44px; }
    .crumbs a:hover { color:var(--text); }
    .crumbs .sep { margin:0 4px; opacity:.6; }
    .crumbs .cur { color:var(--text); }

    /* Catalog pages (styles index / category / style / use-case) */
    .eyebrow { display:inline-block; font:700 .8rem/1 var(--font-display); letter-spacing:.12em;
      text-transform:uppercase; padding:7px 13px; border:1px solid var(--line); border-radius:999px;
      color:var(--muted); background:var(--surface); }
    .pagehead { padding-top:34px; padding-bottom:6px; }
    .pagehead h1 { font-size:clamp(2rem,5vw,3rem); margin:10px 0 0;
      background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent; }
    .pagehead .lede { color:var(--muted); font-size:1.08rem; max-width:680px; margin:14px 0 0; }
    .notice { max-width:680px; margin:16px 0 0; padding:12px 16px; font-size:.95rem;
      color:var(--muted); background:var(--glass); border:1px solid var(--line);
      border-left:3px solid var(--credit); border-radius:0 12px 12px 0; }
    .search-form { display:flex; gap:10px; max-width:560px; margin:18px 0 0; }
    .search-form input { flex:1; padding:13px 16px; background:var(--surface); color:var(--text);
      border:1px solid var(--line); border-radius:12px; font-size:1rem; }
    .search-form input:focus { outline:none; border-color:var(--violet); box-shadow:var(--glow-sm); }
    /* 44x44, not 40: 44 is the minimum comfortable touch target and 40 fails it. */
    .nav-theme { display:inline-flex; align-items:center; justify-content:center;
      width:44px; height:44px; border-radius:11px; border:1px solid var(--line);
      background:var(--surface); color:var(--muted); flex-shrink:0; }
    .nav-theme:hover { color:var(--text); border-color:var(--neon); text-decoration:none; }
    .nav-theme { cursor:pointer; padding:0; font:inherit; transition:color .18s ease, border-color .18s ease; }
    .nav-theme:focus-visible { outline:2px solid var(--violet); outline-offset:2px; }
    /* Show the theme being offered, not the one in use: moon on light, sun on dark. The
       media query excludes an explicit light override so the toggle stays truthful when a
       visitor forces light on a dark OS. */
    .theme-ico { display:none; }
    .theme-ico-moon { display:block; }
    :root[data-theme="dark"] .theme-ico-moon { display:none; }
    :root[data-theme="dark"] .theme-ico-sun { display:block; }
    @media (prefers-color-scheme: dark) {
      :root:not([data-theme="light"]) .theme-ico-moon { display:none; }
      :root:not([data-theme="light"]) .theme-ico-sun { display:block; }
    }
    /* Row grid; images render whole at their natural aspect (never cropped/stretched).
       auto-FILL, not auto-fit: auto-fit collapses the unused tracks, so a row holding a
       single tile stretched it across the full 1120px and a 9:16 example painted about
       1076x1913. The two behave identically once a row is full — auto-fill only differs
       when there are fewer tiles than tracks, which is exactly the case being fixed
       (33 collections have one style, and related/search rows are often short). */
    .tile-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
      gap:18px; margin:26px 0; align-items:start; }
    .tile { display:block; color:var(--text); background:var(--glass); border:1px solid var(--line);
      border-radius:18px; overflow:hidden; backdrop-filter:blur(8px);
      transition:transform .18s ease, border-color .18s ease, box-shadow .18s ease; }
    .tile:hover { transform:translateY(-4px); border-color:var(--neon); box-shadow:var(--glow); text-decoration:none; }
    /* Render at the image's natural aspect (width/height attrs), full, never cropped or stretched. */
    .tile img { width:100%; height:auto; display:block; background:var(--surface-2); }
    .tile .noimg { display:flex; align-items:center; justify-content:center; width:100%; aspect-ratio:3/4;
      background:var(--grad); color:var(--ink); font:800 2.4rem/1 var(--font-display); text-transform:uppercase; }
    .tile .tt { display:block; padding:12px 14px; }
    .tile .tt b { font-weight:600; display:block; }
    .tile .tt small { color:var(--muted); font-size:.82rem; }
    .cat-block { padding:30px 0 6px; }
    .cat-block .cat-head { display:flex; align-items:baseline; gap:14px; }
    .cat-block h2 { font-size:1.5rem; margin:0; }
    .cat-block .cat-head a { font-size:.9rem; }
    .example-gallery { columns:3 220px; column-gap:14px; margin:26px 0; }
    .example-gallery img { width:100%; height:auto; display:block; border-radius:16px; margin-bottom:14px; border:1px solid var(--line); }
    .steps-row { display:grid; grid-template-columns:repeat(3,1fr); gap:18px; margin:22px 0; }
    .steps-row .step { background:var(--glass); border:1px solid var(--line); border-radius:16px; padding:22px; backdrop-filter:blur(8px); }
    .steps-row .n { width:34px; height:34px; border-radius:10px; background:var(--grad); color:var(--ink);
      font:800 1rem/34px var(--font-display); text-align:center; box-shadow:var(--glow-sm); }
    .steps-row h3 { margin:14px 0 6px; font-size:1.08rem; }
    .steps-row p { color:var(--muted); margin:0; font-size:.94rem; }
    .cta-band { text-align:center; padding:48px 26px; border-radius:24px; margin:40px 0 0;
      background:linear-gradient(120deg, rgba(255,79,216,.12), rgba(139,92,255,.14), rgba(34,211,238,.12));
      border:1px solid var(--neon); box-shadow:var(--glow); }
    .cta-band h2 { font-size:clamp(1.6rem,4vw,2.2rem); margin:0 0 10px;
      background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent; }
    .cta-band p { color:var(--muted); margin:0 0 20px; }
    @media (max-width:680px){ .steps-row { grid-template-columns:1fr; } }

    /* Blog */
    .post-meta { color:var(--muted); font-size:.9rem; margin:12px 0 0; }
    /* Cap the height, don't stretch to the container. Blog covers fall back to a style
       example, and examples are 9:16 since the portrait-output change — at width:100% a
       607x1080 cover painted ~1076x1914, nearly two screens tall, as the LCP element.
       width/height stay auto so the intrinsic ratio (and the width/height attrs) still
       prevent layout shift; on phones max-width binds first and it fills the column. */
    .post-cover { display:block; width:auto; height:auto; max-width:100%; max-height:620px;
      margin:22px auto 0; border-radius:18px; border:1px solid var(--line); }
    .post-card .tt { display:flex; flex-direction:column; gap:6px; }
    .post-card .post-date { color:var(--faint); font-size:.78rem; }
    .pager { display:flex; justify-content:space-between; gap:14px; margin:14px 0 6px; }
    /* Rendered Markdown article body */
    .article { max-width:760px; margin:26px auto 0; color:var(--text); font-size:1.05rem; }
    .article h2 { font-size:1.5rem; margin:34px 0 10px; }
    .article h3 { font-size:1.2rem; margin:26px 0 8px; }
    .article p { color:var(--muted); margin:0 0 16px; }
    .article ul, .article ol { color:var(--muted); margin:0 0 16px; padding-left:22px; }
    .article li { margin:6px 0; }
    .article a { color:var(--violet); }
    .article img { display:block; width:auto; height:auto; max-width:100%; max-height:620px;
      margin:18px auto; border-radius:14px; border:1px solid var(--line); }
    .article blockquote { margin:18px 0; padding:12px 18px; border-left:3px solid var(--violet);
      background:var(--glass); border-radius:0 12px 12px 0; color:var(--muted); }
    .article code { background:var(--surface); border:1px solid var(--line); border-radius:6px; padding:2px 6px; font-size:.92em; }
    .article pre { background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:16px; overflow-x:auto; }
    .article pre code { background:none; border:none; padding:0; }
    .article table { width:100%; border-collapse:collapse; margin:18px 0; }
    .article th, .article td { border:1px solid var(--line); padding:8px 12px; text-align:left; }

    /* Shared content (legal pages) */
    .doc { padding-top:48px; padding-bottom:20px; }
    .doc h1 { font-size:2.1rem; margin:0 0 6px; }
    .doc h2 { font-size:1.25rem; margin:34px 0 10px; }
    .doc .updated { color:var(--muted); font-size:.9rem; margin:0 0 22px; }
    .card { background:var(--glass); border:1px solid var(--line); border-radius:16px; padding:22px 26px; margin:22px 0; backdrop-filter:blur(8px); }
    code { background:var(--surface); border:1px solid var(--line); border-radius:6px; padding:2px 6px; }
    label { display:block; margin:14px 0 6px; color:var(--muted); font-size:.92rem; }
    input, textarea {
      width:100%; padding:13px 14px; background:var(--bg); color:var(--text);
      border:1px solid var(--line); border-radius:12px; font-size:1rem; font-family:inherit;
    }
    input:focus, textarea:focus { outline:none; border-color:var(--violet); }

    /* Mobile responsiveness.
       Breakpoint scale (the only widths allowed anywhere in web/image_tools CSS):
       340 floor / 540 sm / 680 md / 960 lg / 1100 xl / 1280 xxl.
       min-width is only ever a step + 1. Custom properties are illegal in media
       query conditions and there is no CSS build step, so the scale is literals
       pinned by test_breakpoints_follow_the_documented_scale, not a var(). */
    @media (max-width:1280px) and (min-width:1101px){
      .mega-menu-grid { grid-template-columns:repeat(4, minmax(0, 1fr)); }
    }
    /* Collapse the horizontal nav into a hamburger whenever the full row would not fit
       next to the brand (tablets and below). The inline row only shows on comfortable
       desktops, so the header never wraps onto a second line. */
    @media (max-width:1100px){
      /* Burger sits in the right-hand actions group beside the theme toggle. */
      .nav-burger { display:inline-flex; }
      .nav .links {
        /* An absolutely positioned child of a grid container is sized against its GRID
           AREA, not the container (CSS Grid 9.2). Left on `grid-column:2` the drawer
           laid out inside the centre column only: 450px wide pinned to the right half
           of a 900px header. It has to span every column to fill the header. */
        grid-column:1 / -1;
        /* Spanning every column reaches the CONTENT box, so the drawer stopped at the
           wrap's gutter instead of bleeding to the screen edges as it did before the
           grid. The negative offsets take it back out over that padding. */
        position:absolute; left:calc(-1 * var(--gutter)); right:calc(-1 * var(--gutter));
        top:100%; flex-direction:column; gap:8px; align-items:stretch;
        background:var(--nav-bg-solid); backdrop-filter:blur(14px); border-bottom:1px solid var(--line);
        padding:16px 20px 24px; display:none; max-height:calc(100vh - 76px); overflow-y:auto;
        -webkit-overflow-scrolling:touch;
      }
      .nav-toggle:checked ~ .links { display:flex; }
      .nav-dropdown { position:static; width:100%; display:flex; flex-direction:column; }
      .nav-dropdown-btn {
        width:100%; display:flex; align-items:center; justify-content:space-between; padding:12px 14px;
        background:var(--surface); border:1px solid var(--line); font-size:1rem; color:var(--text);
        box-sizing:border-box; border-radius:12px;
      }
      .nav-tools-btn {
        width:100%; display:flex; align-items:center; justify-content:flex-start; padding:12px 14px;
        background:var(--surface); border:1px solid var(--line); font-size:1rem; color:var(--text);
        box-sizing:border-box; border-radius:12px;
      }
      .mega-menu-wrapper {
        position:static; width:100%; max-width:100%; padding:8px 0 0 0;
        opacity:1; visibility:visible; pointer-events:auto; transform:none;
        display:none; box-sizing:border-box;
      }
      .mega-menu-wrapper::before { display:none; }
      .nav-dropdown.is-open .mega-menu-wrapper { display:block; }
      .mega-menu-card {
        padding:14px; border-radius:14px; max-height:300px; overflow-y:auto;
        box-shadow:var(--shadow-md); box-sizing:border-box;
      }
      .mega-menu-grid {
        grid-template-rows:auto;
        grid-auto-flow:row;
        grid-template-columns:repeat(2, minmax(0, 1fr));
        gap:4px 8px;
      }
      /* Display top 10 categories on mobile screens with See All always visible */
      .mega-menu-grid .mega-cat-item:nth-child(n+11):not(.mega-see-all-btn) {
        display:none !important;
      }
      .tools-mega-card {
        padding:14px; border-radius:14px; max-height:380px; overflow-y:auto;
        box-shadow:var(--shadow-md); box-sizing:border-box;
      }
      .tools-mega-grid {
        grid-template-rows:auto;
        grid-auto-flow:row;
        grid-template-columns:repeat(2, minmax(0, 1fr));
        gap:4px 8px;
      }
      .tools-mega-grid .nav-tool-item:nth-child(n+11):not(.mega-see-all-btn) {
        display:none !important;
      }
      .mega-see-all-btn { display:inline-flex !important; }
      .nav-tool-item { padding:8px 10px; min-height:38px; }
      .nav .links .nav-cta { margin:10px 0 4px; }
    }
    @media (max-width:960px){
      .pagehead { padding-top:26px; padding-bottom:4px; }
      /* Brand spans the row; the four link columns share the width below it. */
      .foot { grid-template-columns:repeat(4,1fr); gap:24px; }
      .foot-brand-col { grid-column:1 / -1; }
      .foot-blurb { max-width:52ch; }
    }
    @media (max-width:680px){
      :root { --gutter:16px; }
      .foot { grid-template-columns:1fr 1fr; gap:20px 24px;
        padding-top:36px; padding-bottom:28px; }
      .tile-grid { grid-template-columns:repeat(2,1fr); gap:12px; }
      .example-gallery { columns:2; column-gap:12px; }
      .nav-inner { min-height:64px; gap:12px; }
      .brand { font-size:1.05rem; }
      .cta-band { padding:36px 20px; }
      .doc { padding-top:32px; padding-bottom:16px; }
    }
    @media (max-width:540px){
      .foot { grid-template-columns:1fr; gap:18px; }
      .mega-menu-grid { grid-template-columns:1fr; gap:3px; }
      .tools-mega-grid { grid-template-columns:1fr; gap:3px; }
    }

    /* Scroll-reveal: content is visible by default. The hidden/animated state
       applies only when JS is active (html.js), so a JS failure, blocked script
       or disabled JS never leaves sections invisible. */
    .js .reveal { opacity:0; transform:translateY(20px); transition:opacity .6s ease, transform .6s ease; }
    .js .reveal.in { opacity:1; transform:none; }
    @media (prefers-reduced-motion:reduce){ .js .reveal { opacity:1; transform:none; transition:none; } }

/* ---------------------------------------------------------------------------
   AI Trends cover masonry (/styles/)
   CSS columns rather than grid: the covers are 9:16 and 1:1 mixed, and columns
   pack uneven heights with no JS and no fixed row track. break-inside is what
   stops a card being split across a column boundary.
   --------------------------------------------------------------------------- */
.cover-masonry {
  columns: 4;
  column-gap: 16px;
  margin: 22px 0 40px;
}

.cover-card {
  position: relative;
  display: block;
  break-inside: avoid;
  margin: 0 0 16px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  text-decoration: none;
  color: var(--text);
}

.cover-card img {
  display: block;
  width: 100%;
  height: auto;
}

/* Collections with no example image yet still need a card of real height, or the
   column packing collapses and the grid reads as broken. */
.cover-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 9 / 16;
  font-size: 2rem;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  color: var(--faint);
}

.cover-meta {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 30px 12px 12px;
  background: linear-gradient(to top, rgba(var(--shadow-rgb), 0.92), rgba(var(--shadow-rgb), 0));
  color: var(--on-scrim);
}

.cover-title {
  font-family: var(--font-display);
  font-size: 0.95rem;
  line-height: 1.25;
}

.cover-cta {
  font-size: 0.78rem;
  opacity: 0.85;
}

/* Hover is a pointer affordance, so only hide the overlay where a pointer exists.
   Touch gets it outright, and :focus-within brings it back for keyboard tabbing. */
@media (hover: hover) {
  .cover-meta {
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .18s ease, transform .18s ease;
  }
  .cover-card:hover .cover-meta,
  .cover-card:focus-within .cover-meta,
  .cover-card:focus-visible .cover-meta {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 1100px) {
  .cover-masonry { columns: 3; }
}

@media (max-width: 680px) {
  .cover-masonry { columns: 2; column-gap: 12px; }
  .cover-card { margin-bottom: 12px; }
}
