/* AMBER: the ExtractlyPDF design system. Warm paper and ink, one amber-orange accent for the PDF, calm one-off motion. See DESIGN.md. */
/* ExtractlyPDF shared stylesheet (site-wide tokens, header, footer, home, tool-page frame, tile glyphs).
   No external requests. Fonts are declared in /fonts/fonts.css (self-hosted Syne + DM Sans, SIL OFL).
   Contrast figures in comments are hand-calculated WCAG ratios; re-check with a checker before shipping. */


/* ---------- Design tokens ---------- */
:root{
  color-scheme:light dark;
  --bg:#faf9f6; --surface:#f2f0eb; --card:#fff;
  --ink:#0f0e0c;          /* on bg 18:1 */
  --muted:#5a5850;        /* on bg 6.8:1 */
  --subtle:#6b695f;       /* on bg 5.2:1 (replaces the old #9a9890, which was 2.7:1) */
  --line:rgba(15,14,12,.12); --line-strong:rgba(15,14,12,.22);
  --accent:#e8521a;       /* decorative / large shapes only (3.5:1 on bg) */
  --brand:#c23f10;        /* buttons: white text 5.2:1; links on bg 5.0:1 */
  --brand-hover:#a8340a;
  --brand-text:#c23f10;   /* orange text on page backgrounds */
  --accent-soft:#fdf0ea;
  --focus:#0b5fff;
  --shadow:0 14px 34px rgba(15,14,12,.10);
  --r:14px; --r-lg:22px;
  --max:1120px;
  /* aliases so the tool.js component rules in tool.css keep working */
  --faint:var(--subtle); --border:var(--line-strong); --radius:var(--r); --accent-dark:var(--brand-hover); --white:var(--card);
  --head:'Syne',system-ui,-apple-system,'Segoe UI',sans-serif;
  --body:'DM Sans',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
}
@media (prefers-color-scheme:dark){
  :root{
    --bg:#13120f; --surface:#1b1a16; --card:#211f1b;
    --ink:#f4f2ec; --muted:#bdbaae; --subtle:#a29f93;
    --line:rgba(255,255,255,.12); --line-strong:rgba(255,255,255,.24);
    --brand-text:#ff8a5c;   /* on dark bg 8:1 */
    --accent-soft:rgba(232,82,26,.16);
    --focus:#7aa7ff;
    --shadow:0 14px 34px rgba(0,0,0,.45);
  }
}

/* category tints: icon boxes only. Never the sole carrier of meaning (every group also has a heading). */
.c-organize{--c:#c23f10;--cbg:#fdf0ea}
.c-to{--c:#1f4f9a;--cbg:#e8f0fb}
.c-from{--c:#5a3fa0;--cbg:#f0ecfb}
.c-edit{--c:#a3274a;--cbg:#fbeaee}
.c-secure{--c:#0f6b5c;--cbg:#e6f4f1}
.c-optimize{--c:#2f6b1f;--cbg:#e9f5e6}
@media (prefers-color-scheme:dark){
  .c-organize{--c:#ff9a73;--cbg:rgba(232,82,26,.18)}
  .c-to{--c:#8db4f5;--cbg:rgba(60,120,220,.18)}
  .c-from{--c:#b9a4f0;--cbg:rgba(130,100,220,.2)}
  .c-edit{--c:#f08aa3;--cbg:rgba(220,70,110,.2)}
  .c-secure{--c:#6fd3bf;--cbg:rgba(40,170,140,.18)}
  .c-optimize{--c:#98d683;--cbg:rgba(90,170,60,.18)}
}

/* ---------- Base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:176px}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;font-family:var(--body);background:var(--bg);color:var(--ink);line-height:1.6;-webkit-font-smoothing:antialiased}
img,svg{max-width:100%}
a{color:var(--brand-text)}
h1,h2,h3{font-family:var(--head);margin:0;line-height:1.1;letter-spacing:-.02em;text-wrap:balance}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
.wrap{max-width:var(--max);margin:0 auto;padding:0 24px}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:12px;top:-60px;background:var(--brand);color:#fff;padding:10px 16px;border-radius:8px;z-index:200}
.skip:focus{top:12px}
:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:6px}
.icon{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}

/* ---------- Header + "All tools" menu (no JS: <details>) ---------- */
.site-head{position:sticky;top:0;z-index:100;background:color-mix(in srgb,var(--bg) 92%,transparent);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.site-head .wrap{display:flex;align-items:center;gap:20px;height:64px}
.logo{font-family:var(--head);font-weight:800;font-size:20px;letter-spacing:-.5px;color:var(--ink);text-decoration:none}
.logo span{color:var(--brand-text)}
.nav{display:flex;align-items:center;gap:6px;margin-left:auto}
.nav a,.mega>summary{font-size:15px;color:var(--ink);text-decoration:none;padding:8px 12px;border-radius:10px;cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px}
.nav a:hover,.mega>summary:hover,.mega[open]>summary{background:var(--surface)}
.mega>summary::-webkit-details-marker{display:none}
.mega>summary .icon{transition:transform .2s}
.mega[open]>summary .icon{transform:rotate(180deg)}
.mega{position:static}
/* ALL TOOLS menu: a floating card of mini tiles (glyph badge + short name), grouped by the six categories. Grouped, not one flat
   grid, because people look for a job ("merge", "protect") and the same six names are the homepage chips. Still a native
   <details>: works without JS. Glyphs come from the cached /icons.svg sprite (<use>), so the menu adds almost no markup weight. */
.mega-panel{position:absolute;left:0;right:0;top:64px;padding-top:8px;pointer-events:none}
.site-head .mega-panel>.wrap{display:block;height:auto;max-width:1120px;gap:0}   /* undo the header-row rule that .site-head .wrap would apply here */
.mega-card{pointer-events:auto;background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow);padding:20px 22px 22px;max-height:calc(100vh - 88px);overflow:auto;overscroll-behavior:contain}
.mega-groups{display:grid;grid-template-columns:repeat(3,1fr);gap:22px 28px}
.mg h2{font:600 12px var(--body);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);margin:0 0 8px 4px}
.mgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px}
.mm{--on:0;display:flex;align-items:center;gap:10px;padding:6px;border-radius:12px;border:1px solid transparent;color:var(--ink);text-decoration:none;transition:background-color .2s,border-color .2s}
.mm:focus-visible{--on:1;background:var(--surface);border-color:var(--line)}
@media (hover:hover){.mm:hover{--on:1;background:var(--surface);border-color:var(--line)}}
.mb{position:relative;flex:none;width:42px;height:42px;border-radius:12px;background:var(--bgf,var(--cbg));color:var(--c);display:grid;place-items:center}
.mb svg{width:32px;height:32px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;overflow:visible}
.mb .nd{position:absolute;top:-3px;right:-3px;width:10px;height:10px;border-radius:50%;background:var(--brand);border:2px solid var(--card)}
.mn{font-size:14px;line-height:1.25;font-weight:500;min-width:0}
@media (max-width:1000px){.mega-groups{grid-template-columns:repeat(2,1fr)}}
@media (max-width:860px){.nav .hide-sm{display:none}}
/* phones: a full-width sheet under the header; the card scrolls inside, groups stack, mini tiles stay 2 across */
@media (max-width:700px){
  .mega-panel{padding-top:0}
  .mega-panel>.wrap{padding:0}
  .mega-card{border-radius:0 0 var(--r-lg) var(--r-lg);border-left:0;border-right:0;max-height:calc(100vh - 64px);max-height:calc(100dvh - 64px);padding:16px 16px 20px}
  .mega-groups{grid-template-columns:1fr;gap:16px}
}
@media (prefers-reduced-motion:no-preference){
  /* one-off micro-animation, driven by --on like the homepage tiles (the mini glyphs are <use> clones, so the whole glyph moves) */
  .mb svg{transform:scale(calc(1 + var(--on,0) * .14)) rotate(calc(var(--on,0) * -5deg));transition:transform .35s cubic-bezier(.3,1.25,.5,1)}
}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:8px;font:600 16px var(--body);padding:14px 24px;border-radius:12px;border:1.5px solid transparent;text-decoration:none;cursor:pointer;transition:transform .15s,background-color .2s,box-shadow .2s,border-color .2s}
.btn-primary{background:var(--brand);color:#fff}
.btn-primary:hover{background:var(--brand-hover);box-shadow:0 8px 20px rgba(194,63,16,.28)}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line-strong)}
.btn-ghost:hover{border-color:var(--ink)}
.btn:active{transform:translateY(1px)}

/* ---------- Hero (landing) ---------- */
.hero{padding:72px 0 48px;position:relative;overflow:hidden}
.hero::before{content:"";position:absolute;inset:-20% -10% auto auto;width:640px;height:640px;background:radial-gradient(closest-side,rgba(232,82,26,.16),transparent);pointer-events:none;z-index:-1}
.hero .wrap{display:grid;grid-template-columns:1.1fr .9fr;gap:56px;align-items:center}
.pill{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--brand-text);background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 30%,transparent);padding:6px 14px;border-radius:99px;margin-bottom:20px}
.pill i{width:7px;height:7px;border-radius:50%;background:var(--accent)}
.hero h1{font-size:clamp(36px,5.2vw,60px);letter-spacing:-.035em;margin-bottom:18px}
.hero h1 em{font-style:normal;color:var(--brand-text)}
.hero .lede{font-size:18px;color:var(--muted);max-width:520px;margin-bottom:28px}
.hero .cta{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:28px}
.jobs-label{font-size:13px;font-weight:600;color:var(--subtle);margin-bottom:10px}
.jobs{display:flex;flex-wrap:wrap;gap:8px}
.jobs a{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:99px;background:var(--card);border:1px solid var(--line);color:var(--ink);text-decoration:none;font-size:14px;transition:border-color .2s,transform .2s,background-color .2s}
.jobs a:hover{border-color:var(--accent);transform:translateY(-2px)}
.jobs .icon{color:var(--brand-text);font-size:16px}

/* hero visual: a drop zone receiving a file. Decorative (aria-hidden). Fixed aspect ratio = no layout shift. */
.scene{aspect-ratio:1/1;width:100%;max-width:440px;margin-inline:auto;position:relative;border-radius:var(--r-lg);background:linear-gradient(160deg,var(--card),var(--surface));border:1px solid var(--line);box-shadow:var(--shadow);display:grid;place-items:center}
.visual{display:grid;gap:14px;justify-items:center}
.scene>svg{width:84%;height:84%;overflow:visible}
.scene .dc{fill:var(--doc);stroke:var(--docline);stroke-width:1.2}
.scene .dc.hi{stroke:var(--pdf);stroke-width:1.8}
.scene .sk{fill:none;stroke:var(--skel);stroke-width:5;stroke-linecap:round}
.scene .ar{fill:none;stroke:var(--pdf);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.scene .sun{fill:var(--sun)}
.scene .hbar{fill:var(--pdf)}
.scene .barx{fill:none;stroke:#fff;stroke-opacity:.5;stroke-width:5;stroke-linecap:round}
.scene .photo{fill:var(--accent-soft)}
.scene .back,.scene .mid,.scene .front{transform-box:fill-box;transform-origin:center}
.scene .badge{position:absolute;right:8%;bottom:8%;display:flex;align-items:center;gap:8px;background:var(--ink);color:var(--bg);font-size:13px;font-weight:600;padding:8px 14px;border-radius:99px}
.scene .badge .icon{color:#6fd68b}
.scene .chip{position:absolute;font-size:12px;font-weight:600;color:var(--c);background:var(--cbg);border-radius:99px;padding:5px 12px}
.scene .chip:nth-of-type(1){left:8%;top:10%}
.scene .chip:nth-of-type(2){right:8%;top:20%}
.scene .chip:nth-of-type(3){left:10%;bottom:20%}
@media (max-width:860px){
  .hero{padding-top:40px}
  .hero .wrap{grid-template-columns:1fr;gap:36px}
  .scene{max-width:320px}
}

/* ---------- Sections ---------- */
section{padding:64px 0}
.eyebrow{font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--brand-text);margin-bottom:10px}
.h2{font-size:clamp(28px,3.6vw,40px);margin-bottom:12px}
.sec-sub{color:var(--muted);max-width:620px;font-size:17px}
.band{background:var(--surface);border-block:1px solid var(--line)}

/* category nav + search */
.toolbar{position:sticky;top:64px;z-index:50;background:color-mix(in srgb,var(--bg) 94%,transparent);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.toolbar .wrap{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;padding-top:8px;padding-bottom:8px}
.cats{display:flex;flex-wrap:wrap;gap:6px 8px;flex:1 1 520px;min-width:0}
/* Filter chips = a radio group. The radios are visually hidden but focusable; the label is the chip. */
.cats{position:relative;padding:3px}   /* small room for the focus ring */
.cats input{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.cats label{flex:none;display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:99px;border:1px solid var(--line-strong);background:var(--card);color:var(--ink);font-size:14px;white-space:nowrap;cursor:pointer;transition:background-color .2s,border-color .2s,color .2s}
.cats label:hover{border-color:var(--ink)}
.cats label .n{font-size:12px;color:var(--subtle);font-weight:600}
.cats input:checked+label{background:var(--ink);color:var(--bg);border-color:var(--ink);font-weight:600}   /* active = filled, not just a colour change */
.cats input:checked+label .n{color:inherit;opacity:.8}
.cats input:focus-visible+label{outline:3px solid var(--focus);outline-offset:2px}
.status{font-size:14px;color:var(--muted);padding:14px 0 0;min-height:1.6em}
/* The filter. All 26 <li> and their links stay in the HTML; this only hides them visually. */
.finder:has(#f-organize:checked) .grid>li:not([data-cat~=organize]),
.finder:has(#f-to-pdf:checked) .grid>li:not([data-cat~=to-pdf]),
.finder:has(#f-from-pdf:checked) .grid>li:not([data-cat~=from-pdf]),
.finder:has(#f-edit:checked) .grid>li:not([data-cat~=edit]),
.finder:has(#f-security:checked) .grid>li:not([data-cat~=security]),
.finder:has(#f-optimize:checked) .grid>li:not([data-cat~=optimize]){display:none}
.search{position:relative;flex:0 1 220px;margin-left:auto}
.search input{width:100%;font:inherit;font-size:15px;padding:9px 12px 9px 36px;border-radius:99px;border:1px solid var(--line-strong);background:var(--card);color:var(--ink)}
.search input::placeholder{color:var(--subtle)}
.search .icon{position:absolute;left:12px;top:50%;margin-top:-8px;font-size:16px;color:var(--subtle)}
@media (max-width:700px){
  .toolbar{position:static}
  .search{flex:1 1 100%;margin-left:0}
  html{scroll-padding-top:72px}
}

/* ONE uniform grid. Every cell is the same size: auto-rows:1fr makes each row as tall as the tallest card, and the
   card itself has a fixed minimum height, a 2-line title clamp and a 3-line blurb clamp, so no card grows or shrinks. */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));grid-auto-rows:1fr;gap:14px;padding-top:16px}
.grid>li,.related>li{display:flex}
.grid>li[hidden]{display:none}

/* TILE: a 112px tinted "stage" holding one big glyph (~76px), then a one-line title and a 3-line blurb. Fixed height, so
   the grid stays uniform. The stage is tinted in the format colour on format tiles (--bgf), else the category tint. */
.card{flex:1;min-height:236px;display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:var(--r);color:var(--ink);text-decoration:none;position:relative;overflow:hidden;transition:transform .2s,box-shadow .2s,border-color .2s}
.stage{flex:none;height:112px;background:var(--bgf,var(--cbg));color:var(--c);display:grid;place-items:center;border-bottom:1px solid var(--line);transition:background-color .25s}
.stage svg{width:76px;height:76px;overflow:visible;stroke-width:1;display:block}   /* thin stroke: 76px / 24 grid x 1 = ~3px lines */
.card .txt{padding:14px 16px 18px}
.card h3{font-size:17px;letter-spacing:-.01em;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card p{font-size:14px;color:var(--muted);line-height:1.45;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.new{position:absolute;top:10px;right:10px;font:700 10px var(--body);letter-spacing:.06em;text-transform:uppercase;background:var(--brand);color:#fff;border-radius:99px;padding:2px 8px}
.card .go{position:absolute;right:14px;bottom:14px;font-size:16px;color:var(--brand-text);opacity:0;transition:opacity .2s}

/* small icon badge: used only by the compact "row" variant (related tools on tool pages) */
.card .ico{flex:none;width:52px;height:52px;border-radius:16px;background:var(--bgf,var(--cbg));color:var(--c);display:grid;place-items:center}
.card .ico svg{width:30px;height:30px}
.card.row{min-height:0;flex-direction:row;align-items:center;gap:14px;padding:14px 16px}
.card.row .txt{padding:0}
.card.row h3{white-space:normal}
@media (max-width:560px){   /* phones: compact row with a larger thumbnail stage; every tile still identical */
  .grid{grid-template-columns:1fr}
  .grid .card{min-height:112px;flex-direction:row;align-items:stretch}
  .grid .stage{width:132px;height:auto;border-bottom:0;border-right:1px solid var(--line)}
  .grid .stage svg{width:60px;height:60px}
  .grid .card .txt{padding:12px 14px;min-width:0;align-self:center}
}

/* "ON" STATE. One custom property, --on (0 or 1), is set by hover (hover-capable devices only) or keyboard focus.
   Everything animated reads it, so each icon needs no hover/focus selector of its own, and touch screens never get a
   sticky hover because (hover:hover) is false there. Custom properties inherit into the inline <svg>. */
.card:focus-visible{--on:1;box-shadow:var(--shadow);border-color:color-mix(in srgb,var(--accent) 55%,var(--line))}
.card:focus-visible .stage{background:color-mix(in srgb,var(--c) 18%,var(--card))}
.card:focus-visible .go{opacity:1}
@media (hover:hover){
  .card:hover{--on:1;transform:translateY(-3px);box-shadow:var(--shadow);border-color:color-mix(in srgb,var(--accent) 55%,var(--line))}
  .card:hover .stage{background:color-mix(in srgb,var(--c) 18%,var(--card))}   /* static tint change, also under reduced motion */
  .card:hover .go{opacity:1}
}
.empty{padding:24px;color:var(--muted)}

/* ---------- How it works + privacy proof ---------- */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:32px;counter-reset:s}
.step{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding:24px;counter-increment:s}
.step::before{content:counter(s);display:grid;place-items:center;width:36px;height:36px;border-radius:50%;background:var(--accent-soft);color:var(--brand-text);font:800 16px var(--head);margin-bottom:14px}
.step h3{font-size:18px;margin-bottom:6px}
.step p{color:var(--muted);font-size:15px}

.proof{background:#14130f;color:#f4f2ec;border-radius:var(--r-lg);padding:44px;display:grid;grid-template-columns:1fr 1fr;gap:40px}
.proof .eyebrow{color:#ff8a5c}
.proof h2{font-size:clamp(26px,3.2vw,36px);margin-bottom:12px}
.proof p,.proof li{color:#cfccc1}
.proof a{color:#ff9a73}
.flow{display:grid;gap:0;counter-reset:f}
.flow li{position:relative;padding:0 0 22px 48px;counter-increment:f}
.flow li::before{content:counter(f);position:absolute;left:0;top:0;width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.1);display:grid;place-items:center;font-weight:700;color:#fff}
.flow li:not(:last-child)::after{content:"";position:absolute;left:15px;top:36px;bottom:4px;width:2px;background:rgba(255,255,255,.14)}
.flow strong{display:block;color:#fff}
.ticks{display:grid;gap:10px;margin-top:20px}
.ticks li{display:flex;gap:10px;align-items:flex-start}
.ticks .icon{color:#6fd68b;margin-top:4px;font-size:18px}
.limits{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:28px}
.limit{background:rgba(255,255,255,.07);border-radius:12px;padding:14px 16px}
.limit b{display:block;font:700 20px var(--head);color:#fff}
.limit span{font-size:13px;color:#cfccc1}
@media (max-width:860px){
  .steps{grid-template-columns:1fr}
  .proof{grid-template-columns:1fr;padding:28px 22px;gap:28px}
  .limits{grid-template-columns:1fr 1fr}
}

/* FAQ (shared with tool page) */
.faq details{border-bottom:1px solid var(--line);padding:4px 0}
.faq summary{cursor:pointer;font-weight:600;padding:14px 32px 14px 0;position:relative;list-style:none}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:6px;top:50%;width:9px;height:9px;margin-top:-7px;border-right:2px solid var(--subtle);border-bottom:2px solid var(--subtle);transform:rotate(45deg);transition:transform .2s}
.faq details[open] summary::after{transform:rotate(-135deg);margin-top:-2px}
.faq details p{color:var(--muted);padding:0 0 16px;max-width:660px}

/* sign-up */
.signup{text-align:center}
.signup form{display:flex;gap:8px;max-width:440px;margin:20px auto 8px}
.signup input{flex:1;min-width:0;font:inherit;padding:13px 16px;border-radius:12px;border:1px solid var(--line-strong);background:var(--card);color:var(--ink)}
.signup input::placeholder{color:var(--subtle)}
.fine{font-size:13px;color:var(--subtle)}

/* ---------- Long-form pages (privacy policy, contact): same header, footer, tokens and dark mode as the rest ---------- */
.doc{max-width:1000px;margin:0 auto;padding:40px 24px 72px;display:grid;grid-template-columns:210px minmax(0,680px);gap:48px;align-items:start}
.doc-head{grid-column:1 / -1}
.doc-head h1{font-size:clamp(32px,4.4vw,44px);letter-spacing:-.03em;margin-bottom:6px}
.doc-head .meta{color:var(--subtle);font-size:14px}
.toc{position:sticky;top:96px;font-size:14px}
.toc h2{font:600 12px var(--body);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);margin:0 0 10px}
.toc ul{display:grid;gap:2px;border-left:1px solid var(--line)}
.toc a{display:block;padding:4px 0 4px 14px;margin-left:-1px;border-left:2px solid transparent;color:var(--muted);text-decoration:none}
.toc a:hover{color:var(--ink);border-left-color:var(--accent)}
.prose-doc{font-size:16px;line-height:1.75}
.prose-doc h2{font-size:22px;letter-spacing:-.02em;margin:40px 0 10px;scroll-margin-top:96px}
.prose-doc h2:first-of-type{margin-top:0}
.prose-doc p,.prose-doc li{color:var(--muted)}
.prose-doc p{margin:0 0 14px}
.prose-doc ul{list-style:disc;padding-left:22px;display:grid;gap:6px;margin-bottom:14px}
.prose-doc strong{color:var(--ink);font-weight:600}
.summary{background:linear-gradient(180deg,var(--accent-soft),var(--card) 90%);border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line));border-radius:var(--r);padding:18px 22px;margin-bottom:36px}
.summary>p{margin:0 0 8px;color:var(--ink)}
.summary ul{margin:0}
.contact-form{display:grid;gap:18px;max-width:560px}
.contact-form label{display:grid;gap:6px;font-size:14px;font-weight:500}
.contact-form input,.contact-form select,.contact-form textarea{font:inherit;font-weight:400;padding:11px 13px;border:1px solid var(--line-strong);border-radius:12px;background:var(--card);color:var(--ink)}
.contact-form textarea{min-height:160px;resize:vertical}
.contact-form .hp{position:absolute;left:-9999px}
.contact-form .msg{font-size:14px;min-height:1.6em;margin:0}
.contact-form .msg.err{color:var(--del)}
.contact-form .note{font-size:13px;color:var(--subtle)}
@media (max-width:860px){
  .doc{grid-template-columns:1fr;gap:24px;padding-top:28px}
  .toc{position:static;background:var(--surface);border-radius:var(--r);padding:14px 16px}
  .toc ul{border-left:0;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:2px 12px}
  .toc a{padding:4px 0;border-left:0;margin:0}
}

/* ---------- Footer ---------- */
.site-foot{background:var(--surface);border-top:1px solid var(--line);padding:48px 0 28px;font-size:14px}
.foot-grid{display:grid;grid-template-columns:1.2fr repeat(3,1fr);gap:28px 32px}
.foot-grid h2{font:600 13px var(--body);letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);margin-bottom:10px}
.foot-grid li a{display:block;padding:3px 0;color:var(--ink);text-decoration:none}
.foot-grid li a:hover{color:var(--brand-text);text-decoration:underline}
.foot-note{margin-top:10px;color:var(--muted);max-width:280px}
.foot-base{margin-top:32px;padding-top:18px;border-top:1px solid var(--line);color:var(--subtle);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px}
@media (max-width:860px){.foot-grid{grid-template-columns:1fr 1fr}}
@media (max-width:520px){.foot-grid{grid-template-columns:1fr}}

/* ---------- Tool page ---------- */
.crumbs{font-size:14px;color:var(--subtle);padding:20px 0 0}
.crumbs ol{display:flex;gap:8px;flex-wrap:wrap}
.crumbs li+li::before{content:"/";margin-right:8px;color:var(--subtle)}
.crumbs a{color:var(--muted)}
.tool-hero{padding:18px 0 8px}
.tool-hero .wrap{max-width:820px}
.title-row{display:flex;gap:16px;align-items:center;margin-bottom:10px}
.title-row .ico{width:56px;height:56px;border-radius:16px;background:var(--cbg);color:var(--c);display:grid;place-items:center;font-size:30px;flex:none}
.tool-hero h1{font-size:clamp(30px,4.4vw,44px);letter-spacing:-.03em}
.tool-hero .lede{color:var(--muted);font-size:18px;max-width:640px;margin-bottom:18px}
.facts{display:flex;flex-wrap:wrap;gap:8px 10px;margin-bottom:22px}
.facts li{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:500;padding:5px 12px;border-radius:99px;background:var(--surface);color:var(--muted);border:1px solid var(--line)}
.facts .icon{color:var(--brand-text);font-size:15px}

.tool-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px;box-shadow:0 2px 0 var(--line)}
.drop{position:relative;display:grid;justify-items:center;gap:10px;text-align:center;padding:44px 20px;border:2px dashed var(--line-strong);border-radius:16px;background:var(--bg);cursor:pointer;transition:border-color .2s,background-color .2s,transform .2s}
.drop:hover{border-color:var(--accent);background:var(--accent-soft)}
.drop:has(input:focus-visible){outline:3px solid var(--focus);outline-offset:3px}
.drop .big{width:64px;height:64px;border-radius:50%;background:var(--accent-soft);color:var(--brand-text);display:grid;place-items:center;font-size:30px;transition:transform .25s}
.drop strong{font:700 20px var(--head)}
.drop small{color:var(--muted);font-size:14px}
.drop .btn{margin-top:4px}
.drop.over{border-color:var(--brand);border-style:solid;background:var(--accent-soft);transform:scale(1.01)}
.drop.over .big{transform:translateY(-6px) scale(1.08)}
.reassure{display:flex;gap:8px;align-items:flex-start;font-size:14px;color:var(--muted);margin-top:14px}
.reassure .icon{color:var(--brand-text);margin-top:3px;font-size:16px}

.notice{display:flex;gap:12px;margin-top:16px;padding:14px 16px;border-radius:12px;background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 35%,transparent);font-size:15px}
.notice .icon{color:var(--brand-text);font-size:20px;margin-top:2px}
.notice p+p{margin-top:6px}

/* file row, progress, done */
.file-row{display:flex;align-items:center;gap:12px;padding:12px 14px;background:var(--surface);border-radius:12px}
.file-row .ico{font-size:22px;color:var(--brand-text)}
.file-row span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.file-row small{color:var(--subtle)}
.bar{height:10px;border-radius:99px;background:var(--surface);overflow:hidden;margin-top:14px;border:1px solid var(--line)}
.bar i{display:block;height:100%;width:100%;border-radius:99px;background:linear-gradient(90deg,var(--brand),var(--accent))}
.done{display:flex;gap:16px;align-items:center}
.done .tick{width:52px;height:52px;border-radius:50%;background:#e3f5e8;color:#17703a;display:grid;place-items:center;flex:none}
.done .tick svg{width:28px;height:28px;fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
@media (prefers-color-scheme:dark){.done .tick{background:rgba(70,200,110,.18);color:#6fd68b}}
.done h2{font-size:20px}
.done p{color:var(--muted);font-size:14px}
.btn-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}

/* tool page content */
.prose{max-width:820px;margin:0 auto;padding:0 24px}
.prose h2{font-size:26px;margin:0 0 14px}
.block{padding:40px 0 0}
.how{display:grid;gap:10px;counter-reset:h}
.how li{display:flex;gap:14px;align-items:flex-start;padding:16px;background:var(--card);border:1px solid var(--line);border-radius:var(--r);counter-increment:h}
.how li::before{content:counter(h);flex:none;width:30px;height:30px;border-radius:50%;background:var(--accent-soft);color:var(--brand-text);display:grid;place-items:center;font-weight:800;font-family:var(--head)}
.specs{display:grid;grid-template-columns:repeat(2,1fr);gap:10px 28px;background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:18px 20px}
.specs div{display:flex;justify-content:space-between;gap:12px;padding:8px 0;border-bottom:1px solid var(--line);font-size:15px}
.specs dt{color:var(--muted)}
.specs dd{margin:0;font-weight:600;text-align:right}
@media (max-width:640px){.specs{grid-template-columns:1fr}}
.related{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px}
.also{margin-top:14px;font-size:14px;color:var(--muted)}
.also a{margin-right:12px}

.card .txt{display:flex;flex-direction:column;gap:6px;min-width:0}

/* ---------- Motion: decorative only, and only when the visitor hasn't asked for less ---------- */

/* ---------- FORMAT COLOURS (round 3, kept) ----------
   Generic colours people associate with file types, applied to the glyph and a light tint of the badge. They are only
   colours: no vendor logos or letter tiles. Each has a lighter dark-mode shade. Contrast of glyph on badge >= 3:1. */
:root{
  --pdf:#e8521a;
  --f-word:#2b579a; --f-excel:#217346; --f-ppt:#c43e1c; --f-html:#d14015; --f-img:#2f8f4e; --f-md:#3b3a36;
  --sun:#f2a900;
  --doc:#fff; --docline:#86847a; --skel:#d6d3ca;   /* hero page-stack drawing */
}
@media (prefers-color-scheme:dark){
  :root{
    --pdf:#ff8a5c;
    --f-word:#6b9bf2; --f-excel:#4cb87a; --f-ppt:#ff8a63; --f-html:#ff7a50; --f-img:#5cc27f; --f-md:#d8d5cb;
    --sun:#f2b93b;
    --doc:#2b2925; --docline:#9a978c; --skel:#4a4740;
  }
}
/* On a format tile the glyph (currentColor) and the badge tint take the format colour. Defined after .c-* so they win. */
.f-word{--c:var(--f-word);--bgf:color-mix(in srgb,var(--f-word) 13%,var(--card))}
.f-excel{--c:var(--f-excel);--bgf:color-mix(in srgb,var(--f-excel) 13%,var(--card))}
.f-ppt{--c:var(--f-ppt);--bgf:color-mix(in srgb,var(--f-ppt) 13%,var(--card))}
.f-html{--c:var(--f-html);--bgf:color-mix(in srgb,var(--f-html) 13%,var(--card))}
.f-img{--c:var(--f-img);--bgf:color-mix(in srgb,var(--f-img) 13%,var(--card))}
.f-md{--c:var(--f-md);--bgf:color-mix(in srgb,var(--f-md) 10%,var(--card))}
/* Office-style letter badge (hand-drawn): a square in the format colour with a bold W / X / P stroked in --lt (white in
   light mode, near-black in dark mode, where the badge colour is lighter). --lt is not --on (that one drives animation). */
:root{--lt:#fff}
@media (prefers-color-scheme:dark){:root{--lt:#14130f}}
:is(.stage,.ico) .bdf{fill:currentColor;stroke:none}
/* PAGE-FIRST GLYPH VOCABULARY (round 6): every PDF tool shows a page plus the action on it.
   .pg page (card-filled so overlaps hide what is behind)  .tl mini text lines  .pf action detail in PDF orange
   .pfill solid PDF-orange badge  .nm numeral text  .rbar redaction bar  .dl/.di removed/added line */
:root{--redact:#0f0e0c;--del:#b3261e;--ins:#1d7a3c}
@media (prefers-color-scheme:dark){:root{--redact:#000;--del:#ff8f85;--ins:#6fd68b}}
:is(.stage,.ico) .pg{fill:var(--card)}
:is(.stage,.ico) .tl{stroke-width:.8;opacity:.6}
:is(.stage,.ico) .pfill{fill:var(--pdf);stroke:none}
:is(.stage,.ico) .pfx{fill:var(--pdf);stroke:none}
:is(.stage,.ico) .nm{fill:currentColor;stroke:none;font:700 5.4px var(--body);text-anchor:middle}
:is(.stage,.ico) .pfx.nm{fill:var(--pdf)}
/* Redact: solid near-black bars on a LIGHT page in both modes (in dark mode the page is light paper, so the bars read as blacked-out text) */
:root{--rpage:#fff}
@media (prefers-color-scheme:dark){:root{--rpage:#ece9e0}}
:is(.stage,.ico) .rpg{fill:var(--rpage)}
:is(.stage,.ico) .rbar{fill:var(--redact);stroke:none}
.ic-redact .tl{stroke:#8f8c82;opacity:1}
:is(.stage,.ico) .dl{fill:var(--del);stroke:none}
:is(.stage,.ico) .di{fill:var(--ins);stroke:none}
:is(.stage,.ico) .shade{fill:currentColor;fill-opacity:.2;stroke:none;fill-rule:evenodd}
:is(.stage,.ico) .thick{stroke-width:1.6}
:is(.stage,.ico) .wmk{font:800 3.1px var(--head);fill:var(--pdf);stroke:none;text-anchor:middle;letter-spacing:.1px}   /* stamp frame + text, kept inside the page */
:is(.stage,.ico) .pf.thin{stroke-width:.8}
:is(.stage,.ico) .wr2{fill:var(--card);stroke-width:1.8}
:is(.stage,.ico) .kh{fill:var(--lt);stroke:none}
:is(.stage,.ico) .lt{fill:none;stroke:var(--lt);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
:is(.stage,.ico) .pf,.ico .pf{stroke:var(--pdf)}     /* the PDF part of a converter glyph is always PDF orange */
:is(.stage,.ico) .sn,.ico .sn{fill:var(--sun);stroke:none}   /* sun in the image glyph: decorative accent only; the frame and hills carry the shape */

/* TILE ICONS (round 2, restored). Pattern: animated parts of an inline <svg> carry class "p"; their transform is a
   function of --on (0 or 1, set on the tile by hover/focus, see above). The browser tweens between the two poses,
   0.45 s, once per hover, no loop, no JS. Only transform, opacity and stroke-dashoffset change: no layout. Everything
   sits inside no-preference, so with reduced motion the icons stay still and the tile only changes tint. */
@media (prefers-reduced-motion:no-preference){
  .ic .p{transform-box:fill-box;transform-origin:center;transition:transform .45s cubic-bezier(.3,1.25,.5,1),opacity .4s ease,stroke-dashoffset .5s ease-out}

  /* shared: "convert" icons, an arrow pushes through (override --dx/--dy per icon) */
  .ic .arr{transform:translate(calc(var(--on,0) * var(--dx,3px)),calc(var(--on,0) * var(--dy,0px)))}
  .ic-extract-images{--dx:2px;--dy:-2px}

  /* Organize */
  .ic-merge .l{transform:translateY(calc(var(--on,0) * 1.6px))}      /* the two small pages move toward each other */
  .ic-merge .r{transform:translateY(calc(var(--on,0) * -1.6px))}
  .ic-split .l{transform:translateY(calc(var(--on,0) * -1.6px))}     /* the two halves move apart */
  .ic-split .r{transform:translateY(calc(var(--on,0) * 1.6px))}
  .ic-extract-pages .lift{transform:translate(calc(var(--on,0) * 1px),calc(var(--on,0) * -2px))}   /* the picked page lifts out */
  .ic-extract-pages .bdg{transform:scale(calc(1 + var(--on,0) * .2))}
  .ic-delete-pages .bdg{transform:scale(calc(1 + var(--on,0) * .2)) rotate(calc(var(--on,0) * 90deg))}
  .ic-delete-pages .pgx{transform:translateX(calc(var(--on,0) * -1px)) rotate(calc(var(--on,0) * -4deg))}
  .ic-organize .l{transform:translateX(calc(var(--on,0) * 11px))}    /* the two pages swap places */
  .ic-organize .r{transform:translateX(calc(var(--on,0) * -11px))}
  .ic-rotate .tilt{transform:rotate(calc(var(--on,0) * 90deg))}      /* the page turns a quarter */

  /* Optimize */
  .ic-compress .pgc{transform:scale(calc(1 - var(--on,0) * .14),calc(1 - var(--on,0) * .05))}   /* page is squeezed */
  .ic-compress .a1{transform:translateX(calc(var(--on,0) * 1.5px))}
  .ic-compress .a2{transform:translateX(calc(var(--on,0) * -1.5px))}
  .ic-repair .w{transform:rotate(calc(var(--on,0) * 35deg))}         /* wrench turns */

  /* Security */
  .ic-protect .sh{transform:translateY(calc((1 - var(--on,0)) * -1.6px))}   /* shackle drops and closes */
  .ic-unlock .sh{transform-origin:left bottom;transform:rotate(calc(var(--on,0) * -28deg))}   /* shackle swings open */
  .ic-redact .rbar{transform-origin:left center;transform:scaleX(calc(.3 + var(--on,0) * .7))}  /* bars sweep across the text */

  /* Edit & review */
  .ic-edit .caret{transform:translateX(calc(var(--on,0) * 1.5px))}   /* text cursor moves on */
  .ic-edit .tt{transform:scale(calc(1 + var(--on,0) * .12))}
  .ic-crop .marks{transform:scale(calc(1 - var(--on,0) * .1))}       /* crop marks pull in */
  .ic-crop .shade{opacity:calc(.6 + var(--on,0) * .4)}
  .ic-compare .pl{transform:translateX(calc(var(--on,0) * -1.4px))}  /* the two pages nudge apart */
  .ic-compare .pr{transform:translateX(calc(var(--on,0) * 1.4px))}
  .ic-compare .dl,.ic-compare .di{transform-origin:left center;transform:scaleX(calc(.4 + var(--on,0) * .6))}   /* differences light up */
  .ic-page-numbers .num{transform:scale(calc(1 + var(--on,0) * .3))}
  .ic-watermark .wmk{transform:scale(calc(1 + var(--on,0) * .1));opacity:calc(.6 + var(--on,0) * .4)}
  .ic-scan .ln{transform:translateY(calc(var(--on,0) * 6px - 3px))}  /* scan line passes over the page */

  /* Office letter badge: pops and tilts slightly, while the arrow pushes toward the PDF */
  .ic-word .bd,.ic-excel .bd,.ic-powerpoint .bd{transform:scale(calc(1 + var(--on,0) * .14)) rotate(calc(var(--on,0) * -5deg))}

  /* Convert to PDF (html) */
  .ic-html .l{transform:translateX(calc(var(--on,0) * -2px))}
  .ic-html .r{transform:translateX(calc(var(--on,0) * 2px))}
  .ic-html .sl{transform:rotate(calc(var(--on,0) * 14deg))}
}

@media (prefers-reduced-motion:no-preference){
  /* hero (from the live site's fanned page stack): pages fan out once, then front page, badge and chips float gently */
  .scene .back{animation:fan 1.1s .1s cubic-bezier(.3,1.2,.5,1) both}
  .scene .mid{animation:fan2 1.1s .2s cubic-bezier(.3,1.2,.5,1) both}
  .scene .front{animation:floaty 7s ease-in-out infinite}
  .scene .badge{animation:floaty 6s -2s ease-in-out infinite}
  .scene .chip{animation:bob 6s ease-in-out infinite}
  .scene .chip:nth-of-type(2){animation-delay:-2s}
  .scene .chip:nth-of-type(3){animation-delay:-4s}
  @keyframes fan{from{transform:rotate(0) translate(18px,6px);opacity:.2}}
  @keyframes fan2{from{transform:rotate(0) translate(8px,4px);opacity:.2}}
  @keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
  @keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}

  /* hero text enters */
  .hero .wrap>div:first-child>*{animation:rise .6s ease both}
  .hero .wrap>div:first-child>*:nth-child(2){animation-delay:.06s}
  .hero .wrap>div:first-child>*:nth-child(3){animation-delay:.12s}
  .hero .wrap>div:first-child>*:nth-child(4){animation-delay:.18s}
  .hero .wrap>div:first-child>*:nth-child(5){animation-delay:.24s}
  @keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

  /* pill dot */
  .pill i{animation:pulse 2s ease-in-out 2}   /* finite (4 s): under the 5 s WCAG 2.2.2 threshold */
  @keyframes pulse{50%{opacity:.35;transform:scale(.7)}}

  /* filtering: cards that appear fade and rise a little (they replay whenever display switches from none) */
  .grid>li{animation:cardIn .28s ease-out both}
  @keyframes cardIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

  /* mega menu opens */
  .mega[open] .mega-panel{animation:fade .18s ease-out}
  @keyframes fade{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

  /* upload zone idle hint + drag-over */
  .drop .big{animation:hint 1.6s ease-in-out 2}   /* finite (3.2 s), not a loop */
  .drop.over .big{animation:none}
  @keyframes hint{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}

  /* progress shimmer + done tick draws itself */
  /* indeterminate on purpose: the server reports no percentage, and we never fake one */
  .bar i{width:40%;animation:slide 1.3s ease-in-out infinite}
  @keyframes slide{from{transform:translateX(-100%)}to{transform:translateX(250%)}}
  .done .tick svg path{stroke-dasharray:30;stroke-dashoffset:30;animation:draw .5s .1s ease-out forwards}
  .done .tick{animation:tickpop .4s ease-out both}
  @keyframes draw{to{stroke-dashoffset:0}}
  @keyframes tickpop{from{transform:scale(.6)}60%{transform:scale(1.1)}to{transform:scale(1)}}

  /* scroll reveal, only where the browser supports scroll-driven animations; elsewhere content is simply there */
  @supports (animation-timeline:view()){
    /* applied to the <li> wrapping a card, not the card itself, so the card's own hover transform still works */
    .reveal{animation:revealIn linear both;animation-timeline:view();animation-range:entry 0% entry 35%}
    @keyframes revealIn{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}
  }
}
/* "Pause motion" (WCAG 2.2.2): the only things that still loop longer than 5 s are the hero float and chip bob. A hidden
   checkbox (first element in <body>) plus :has() stops them and leaves the still picture. No JS, nothing stored. */
body:has(#calm:checked) .scene :is(*,*::before){animation:none!important}
.calm{display:inline-flex;align-items:center;gap:8px;padding:7px 14px;border-radius:99px;border:1px solid var(--line-strong);background:var(--card);color:var(--ink);font-size:13px;cursor:pointer;white-space:nowrap}
.calm:hover{border-color:var(--ink)}
.calm .off{display:none}
body:has(#calm:checked) .calm{background:var(--ink);color:var(--bg);border-color:var(--ink)}
body:has(#calm:checked) .calm .on{display:none}
body:has(#calm:checked) .calm .off{display:inline}
body:has(#calm:focus-visible) .calm{outline:3px solid var(--focus);outline-offset:2px}
/* reduced motion: keep only instant colour/shadow feedback, drop movement */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms!important;scroll-behavior:auto!important}
  .card:hover,.jobs a:hover{transform:none}
}

/* small glyph badges (tool-page title, related cards) reuse the tile glyphs */
.ico .ic{width:100%;height:100%;overflow:visible;stroke-width:1}
.title-row .ico{background:var(--bgf,var(--cbg))}
.title-row .ico .ic{width:38px;height:38px}

/* build.py helpers */
.narrow{max-width:820px}
h2.gap{margin-top:20px}
ol{margin:0;padding:0}
.crumbs ol,.how,.flow,.steps{list-style:none}
.block.last{padding-bottom:64px}
.pages:empty,.fields:empty,.files:empty{display:none}
.doc.single{grid-template-columns:minmax(0,680px)}
.doc-head .meta.lead{font-size:16px;color:var(--muted)}
.contact-form .btn{justify-content:center}
/* doc pages have no chip bar: anchors only need to clear the 64px header (html scroll-padding-top is 176px elsewhere) */
html:has(.doc){scroll-padding-top:88px}
.prose-doc h2,.prose-doc h2[id],.summary[id]{scroll-margin-top:0}
