/* shared/site.css — common tokens, nav, footer, cookie banner, icon system,
   and tool-component styles shared by every standalone (MPA) page. Extracted
   verbatim from index.html's <style> block — same selectors/values, so nothing
   visually drifts from the SPA pages. Not used by index.html itself (it keeps
   its own inline <style>); only standalone pages like /gif/ link this file. */

/* The icon SVGs/mask rules live in their own file, icons.css, so both
   this file (every tool page, via this @import) and index.html (via its
   own separate <link>, since it doesn't load the rest of this file) point
   at the exact same source instead of each keeping a hand-duplicated
   copy — see icons.css's own header comment for why that mattered.
   Versioned exactly like index.html's own <link> to it, and for the same
   reason every other shared file is: this file's own ?v= bump forces a
   fresh fetch of site.css itself, but browsers cache each sub-resource
   an @import pulls in by ITS OWN URL, independent of the parent's —
   without a query param here, a page that already had icons.css cached
   from an earlier visit keeps rendering the OLD icon set even after
   site.css's version changes and a new icon gets added, since the
   @import's target URL never changed. Bump this alongside icons.css's
   own <link> in index.html whenever icons.css's content changes. */
@import url("icons.css?v=2");
/* Same reasoning: the 4 category texture recipes (image/video/sound/
   code) live in textures.css so any tool's own .tool-app banner can opt
   into the same treatment its homepage card uses via data-category,
   instead of that logic staying private to index.html's card grid.
   Versioned for the same cache-busting reason as icons.css above. */
@import url("textures.css?v=1");

/* ===== TOKENS ===== */
:root{
  --context-yellow:#F6D44A;
  /* Structural tokens — real light-mode values here, real dark-mode
     values in the :root[data-theme="dark"] block below. These replace
     the old approach (one dark-only value + a filter:invert on
     #app-shell to fake light mode at paint time), which never round
     -tripped correctly for every hue and needed a growing pile of
     per-element exceptions to patch. Brand/accent colors (the 5 tool
     colors, --shape-color) are deliberately NOT here — they're meant to
     render identically in both themes, so they stay plain hex at their
     point of use. */
  --bg:#ffffff;
  --border:rgba(0,0,0,.14);
  --border-strong:rgba(0,0,0,.4);
  --text:#000000;
  --accent:#1e293b;
  --accent2:#475569;
}

:root[data-theme="dark"]{
  --bg:#202124;
  --border:rgba(255,255,255,.14);
  --border-strong:rgba(255,255,255,.4);
  --text:#ffffff;
  --accent:#f1f5f9;
  --accent2:#cbd5e1;
}


*{box-sizing:border-box;}

/* Forces every element's transition off for one paint during a theme
   swap (see applyTheme in this file) — so the light/dark flip is a
   hard cut instead of every component's own ~0.2s transition (buttons,
   .result, etc.) crossfading independently, which reads as one slow,
   uneven fade rather than an instant switch. Removed two frames later,
   so hover/etc. transitions keep working normally afterward. */
.theme-instant, .theme-instant *{
  transition:none !important;
}

html{
  scroll-behavior:smooth;
  /* Decorative background shapes (.cs-shape etc.) intentionally bleed
     past their container's edges via overflow:visible for a parallax
     look — on narrow phones a couple of them (Combine/Cleanly's
     cs-shape-2) bleed past the *right* edge specifically, which browsers
     do turn into real horizontal scroll. Rather than re-tuning each
     shape's per-page offset (fragile — the next new shape reintroduces
     this), clip at the document level: shapes still bleed/clip exactly
     as designed, just never create an actual scrollbar.  */
  overflow-x:hidden;
}

/* Light/dark theming now comes entirely from the --bg/--text/--border/
   --accent tokens above (:root vs :root[data-theme="dark"]) plus each
   brand color's own literal hex at its point of use — no page-wide
   filter, no per-element "cancel the filter" exceptions. Brand colors
   (tool accents, decorative shapes) render identically in both themes
   simply because nothing is inverting them anymore. */

body{
  margin:0;
  font-family:system-ui, sans-serif;
  color:var(--text);
  background:var(--bg);
  min-height:100vh;
}

/* Sticky footer: on short pages (e.g. Context with no PDF loaded yet),
   the active page grows to fill any leftover viewport height so the
   footer sits flush at the bottom instead of leaving a gap of plain
   page background beneath it. */
#app-shell{
  color:var(--text);
  display:flex;
  flex-direction:column;
  min-height:100vh;
}

/* ===== COOKIE CONSENT BANNER ===== */
.cookie-banner[hidden]{
  display:none;
}

/* Per-theme colors, not the invert filter — filter also inverts
   shadows/borders and made this overlay nearly invisible in light mode. */
.cookie-banner{
  position:fixed;
  left:16px;
  right:16px;
  bottom:16px;
  z-index:1000;
  display:flex;
  flex-direction:column;
  gap:14px;
  max-width:520px;
  margin:0 auto;
  padding:20px 24px;
  background:#1d2436;
  border:1px solid rgba(255,255,255,.14);
  border-radius:20px;
}

html[data-theme="light"] .cookie-banner{
  background:#e4e9f5;
  border-color:rgba(29,36,54,.3);
}

.cookie-banner p{
  margin:0;
  font-size:14px;
  line-height:1.5;
  color:#e5e7eb;
}

html[data-theme="light"] .cookie-banner p{
  color:#1d2436;
}

.cookie-banner a{
  color:#f1f5f9;
  text-decoration:underline;
  cursor:pointer;
}

html[data-theme="light"] .cookie-banner a{
  color:#1d2436;
}

.cookie-banner-categories{
  display:flex;
  flex-direction:column;
  gap:4px;
  border-top:1px solid rgba(255,255,255,.14);
  border-bottom:1px solid rgba(255,255,255,.14);
  padding:10px 0;
}

html[data-theme="light"] .cookie-banner-categories{
  border-color:rgba(29,36,54,.25);
}

.cookie-toggle-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  padding:6px 0;
  font-size:14px;
  color:#e5e7eb;
}

.cookie-toggle-row[hidden]{
  display:none;
}

html[data-theme="light"] .cookie-toggle-row{
  color:#1d2436;
}

/* The "> " prefix on each category label is now a real button (was
   plain text baked into the translated string) — clicking it expands
   a short description of that category, without also toggling the
   checkbox next to it (a real risk if this lived inside the <label>
   instead of as its sibling). */
.cookie-cat-row{
  display:flex;
  align-items:center;
  gap:6px;
}

.cookie-cat-row .cookie-toggle-row{
  flex:1;
}

.cookie-cat-arrow{
  flex-shrink:0;
  background:none;
  border:none;
  padding:0;
  font:inherit;
  font-family:"Courier New", Courier, monospace;
  font-weight:700;
  color:#e5e7eb;
  opacity:.6;
  cursor:pointer;
  transition:transform .15s ease, opacity .15s ease;
}

.cookie-cat-arrow:hover,
.cookie-cat-arrow:focus-visible{
  opacity:1;
}

.cookie-cat.open .cookie-cat-arrow{
  transform:rotate(90deg);
}

html[data-theme="light"] .cookie-cat-arrow{
  color:#1d2436;
}

.cookie-cat-detail{
  margin:0 0 6px 20px;
  font-size:12px;
  line-height:1.45;
  color:#e5e7eb;
  opacity:.7;
}

.cookie-cat-detail[hidden]{
  display:none;
}

/* Same recurring bug as .cookie-toggle-row above — an unconditional
   display:flex on .cookie-cat-row alone wouldn't be affected since
   [hidden] targets .cookie-cat itself, but guarding it explicitly
   here too since .cookie-cat has no display of its own to conflict
   with (this is defensive, matching the established pattern rather
   than a currently-observed bug). */
.cookie-cat[hidden]{
  display:none;
}

html[data-theme="light"] .cookie-cat-detail{
  color:#1d2436;
}

.cookie-toggle-status{
  font-family:"Courier New", Courier, monospace;
  font-weight:700;
  color:#ff6b6b;
}

.cookie-toggle-status.is-allowed{
  color:#4ade80;
}

html[data-theme="light"] .cookie-toggle-status{
  color:#dc2626;
}

html[data-theme="light"] .cookie-toggle-status.is-allowed{
  color:#16a34a;
}

.cookie-toggle-row input[type="checkbox"]{
  width:18px;
  height:18px;
  flex:0 0 auto;
  accent-color:#4ade80;
  cursor:pointer;
}

.cookie-toggle-row input[type="checkbox"]:disabled{
  cursor:not-allowed;
  opacity:.6;
}

.cookie-banner-actions{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:10px;
}

/* Feedback for "Confirm choices" — the docked panel doesn't dismiss
   itself, so this is the only visible response. */
.cookie-banner-saved{
  margin-right:auto;
  font-family:monospace;
  font-weight:700;
  font-size:12px;
  letter-spacing:.05em;
  color:#4ade80;
  opacity:0;
  transition:opacity .2s ease;
}

.cookie-banner-saved.is-visible{
  opacity:1;
}

html[data-theme="light"] .cookie-banner-saved{
  color:#16a34a;
}

.cookie-banner-saved-cursor{
  font-family:"Courier New", Courier, monospace;
  font-weight:700;
  font-size:11px;
  letter-spacing:.05em;
  color:#4ade80;
}

html[data-theme="light"] .cookie-banner-saved-cursor{
  color:#16a34a;
}

/* Docked panel auto-saves per toggle, so confirm is redundant there —
   floating prompt still needs it. .needs-consent covers the exception:
   no prior consent means "decline all" changes nothing, so auto-save
   never fires without an explicit confirm. */
.cookie-banner.docked #cookieBannerSave{
  display:none;
}

.cookie-banner.docked.needs-consent #cookieBannerSave{
  display:inline-flex;
  align-items:center;
}

.cookie-banner-actions button{
  height:40px;
  padding:0 18px;
  border-radius:14px;
  border:1px solid rgba(255,255,255,.14);
  cursor:pointer;
  font-weight:700;
  font-size:14px;
  background:rgba(255,255,255,.08);
  color:#e5e7eb;
}

html[data-theme="light"] .cookie-banner-actions button{
  border-color:rgba(29,36,54,.25);
  background:rgba(29,36,54,.06);
  color:#1d2436;
}

.cookie-banner-actions button:hover{
  background:rgba(255,255,255,.14);
}

html[data-theme="light"] .cookie-banner-actions button:hover{
  background:rgba(29,36,54,.12);
}

#cookieBannerAcceptAll{
  background:#4ade80;
  color:#111;
  border-color:#4ade80;
}

#cookieBannerAcceptAll:hover{
  background:#6ee7a3;
}

html[data-theme="light"] #cookieBannerAcceptAll{
  background:#16a34a;
  color:#fff;
  border-color:#16a34a;
}

html[data-theme="light"] #cookieBannerAcceptAll:hover{
  background:#15803d;
}

/* "Accept All" flips to "Disable all" once everything's on, and back
   once everything's off. */
#cookieBannerAcceptAll.is-disable-all{
  background:#ef4444;
  color:#111;
  border-color:#ef4444;
}

#cookieBannerAcceptAll.is-disable-all:hover{
  background:#f87171;
}

html[data-theme="light"] #cookieBannerAcceptAll.is-disable-all{
  background:#dc2626;
  color:#fff;
  border-color:#dc2626;
}

html[data-theme="light"] #cookieBannerAcceptAll.is-disable-all:hover{
  background:#b91c1c;
}

@media (max-width:600px){
  .cookie-banner-actions{
    flex-direction:column-reverse;
  }
  .cookie-banner-actions button{
    width:100%;
  }
}

/* Per-theme colors, same as .engine-status-card — not the invert filter. */
/* Terminal label, inline with the panel's intro text */
/* Uncolored — inherits the panel's text color */
.cookie-dock-inline-label{
  display:inline-flex;
  align-items:center;
  gap:8px;
  margin-right:6px;
  white-space:nowrap;
}

.cookie-dock-title{
  margin-left:6px;
}

/* Re-parent target for the cookie banner on the Cookies page */
.cookie-banner-dock{
  margin-top:8px;
}

/* Must precede the media query — equal specificity means source order
   wins, so a later display:none would beat display:inline-flex at every
   width. */
.cookie-mobile-settings-btn{
  display:none;
  align-items:center;
  margin-top:8px;
  height:44px;
  padding:0 20px;
  border-radius:14px;
  border:1px solid rgba(255,255,255,.14);
  cursor:pointer;
  font-weight:700;
  font-size:14px;
  background:rgba(255,255,255,.08);
  color:#e5e7eb;
}

html[data-theme="light"] .cookie-mobile-settings-btn{
  border-color:rgba(29,36,54,.25);
  background:rgba(29,36,54,.06);
  color:#1d2436;
}

/* No docking on mobile — plain button reopens the floating banner
   instead. */
@media (max-width:768px){
  .cookie-banner-dock{
    display:none;
  }
  .cookie-mobile-settings-btn{
    display:inline-flex;
  }
}

/* Docked = same element, inline instead of position:fixed. Can't tween
   fixed -> static, so the swap is a quick fade instead. */
/* Matches the intro terminal card: 16px radius, 678px wide, spacing
   tuned to land near its ~212px height. */
.cookie-banner.docked{
  position:static;
  left:auto;
  right:auto;
  bottom:auto;
  width:100%;
  max-width:678px;
  margin:0 auto;
  padding:14px 16px;
  gap:8px;
  border-radius:16px;
  font-family:"Courier New", Courier, monospace;
  letter-spacing:.02em;
}

/* Terminal look is docked-only — the floating prompt stays plain
   (system font). */
.cookie-banner.docked p,
.cookie-banner.docked .cookie-toggle-row{
  font-size:15px;
  font-weight:700;
}

.cookie-banner.docked p{
  opacity:.8;
}

.cookie-banner.docked .cookie-banner-categories{
  padding:6px 0;
  gap:0;
}

.cookie-banner.docked .cookie-toggle-row{
  padding:3px 0;
}

.cookie-banner.docked .cookie-banner-actions button{
  font-family:"Courier New", Courier, monospace;
  font-size:15px;
  letter-spacing:.02em;
  border-radius:10px;
}

/* Same reveal logic as the "BC-TOOLS_CLASSIFIED_MEMORY: LEAKED" card:
   at first glance only the title bar shows, and clicking the yellow
   dot reveals the rest. Scoped to .docked specifically — this is the
   settings-recap panel on the dedicated Cookies page, not the
   first-visit floating consent banner, which must always show its
   controls plainly and is untouched by this. */
.cookie-dock-toggle{
  padding:0;
  border:none;
  cursor:pointer;
}

.cookie-dock-toggle:hover,
.cookie-dock-toggle:focus-visible{
  box-shadow:0 0 0 3px rgba(250,204,21,.35);
  outline:none;
}

.cookie-banner.docked:not(.dock-revealed) .cookie-banner-categories,
.cookie-banner.docked:not(.dock-revealed) .cookie-banner-actions{
  display:none;
}

/* ...allowed / ...disabled readout — terminal panel only */
.cookie-toggle-status{
  display:none;
}

.cookie-banner.docked .cookie-toggle-status{
  display:inline;
}

/* Three wordings swapped via CSS, not JS — i18n rewrites innerHTML on
   language change and would clobber a JS-driven swap. */
.cookie-banner-text-docked,
.cookie-banner-text-mobile{
  display:none;
}

.cookie-banner.docked .cookie-banner-text-floating{
  display:none;
}

.cookie-banner.docked .cookie-banner-text-docked{
  display:block;
}

/* Mobile + Cookies page only: drop the "We use cookies" preamble and
   link — visitor is already on that page. */
@media (max-width:768px){
  .cookie-banner.on-cookies-page .cookie-banner-text-floating{
    display:none;
  }
  .cookie-banner.on-cookies-page .cookie-banner-text-mobile{
    display:block;
  }
}

.cookie-banner.cookie-banner-fading{
  opacity:0;
}

.cookie-banner{
  transition:opacity .18s ease;
}

.cookie-settings-btn-dot{
  width:8px;
  height:8px;
  border-radius:50%;
  background:#e5e7eb;
  opacity:.5;
}

html[data-theme="light"] .cookie-settings-btn-dot{
  background:#1d2436;
}

.cookie-settings-btn-cursor{
  animation:cookie-settings-cursor-blink 1s step-end infinite;
}

/* Traffic-light dots on the docked recap panel's title bar — decorative,
   only the yellow one does anything (matches real macOS greying out a
   window's non-functional controls). Ported from the mainpage's
   "classified terminal" easter egg card, which this look is borrowed
   from. */
.engine-status-dot-red{
  background:#ef4444 !important;
  opacity:1 !important;
}

.engine-status-dot-yellow{
  background:#facc15 !important;
  opacity:1 !important;
}

.engine-status-dot-green{
  background:#4ade80 !important;
  opacity:1 !important;
}

.cookie-settings-btn-dot.engine-status-dot-red,
.cookie-settings-btn-dot.engine-status-dot-green{
  background:#6b7280 !important;
  opacity:.6 !important;
}

@keyframes cookie-settings-cursor-blink{
  0%, 100%{ opacity:1; }
  50%{ opacity:0; }
}


.site-nav{
  position:sticky;
  top:0;
  z-index:50;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  height:88px;
  padding:0 28px;
  background:#1d2436;
  border-bottom:1px solid rgba(255,255,255,.08);
}

html[data-theme="light"] .site-nav{
  background:#d4dbee;
}

/* Central confirmation display for nav actions (theme, language,
   copy link) — terminal-styled to match the site's other terminal
   banners. Desktop only: there's no room for it once the nav collapses
   for mobile, and confirmations there would just crowd the brand/menu
   button instead of sitting in open space. */
.nav-terminal{
  position:absolute;
  left:50%;
  top:50%;
  transform:translate(-50%, -50%);
  padding:8px 16px;
  color:#4ade80;
  font-family:"Courier New", Courier, monospace;
  font-size:14px;
  font-weight:700;
  letter-spacing:.02em;
  white-space:nowrap;
  opacity:0;
  pointer-events:none;
  transition:opacity .2s ease;
  z-index:55;
}

.nav-terminal.show{
  opacity:1;
}

.nav-terminal-prompt{
  opacity:.7;
}

.nav-terminal-cursor{
  animation:copy-toast-blink 1s step-end infinite;
}

@media (max-width:768px){
  .nav-terminal{
    display:none;
  }
}

.site-nav-brand{
  display:flex;
  align-items:center;
  gap:14px;
  font-size:42px;
  font-weight:900;
  text-decoration:none;
  letter-spacing:-0.02em;
  white-space:nowrap;
  background:none;
  border:none;
  cursor:pointer;
  font-family:inherit;
}

.brand-text{
  color:#E3E8F8;
}

html[data-theme="light"] .brand-text{
  color:#121727;
}

/* ===== ICON SLOTS =====
   Icons are base64 background-images via --icon-* custom properties,
   applied through .icon-* classes on a sized span:
   <span class="gfx-md icon-convert" role="img" aria-label="...">.
   New icon: add --icon-X, add .icon-X{background-image:var(--icon-X)},
   use class="gfx-sm|md|lg icon-X". */
img.gfx-md, img.gfx-lg,
svg.gfx-md, svg.gfx-lg,
span.gfx-md, span.gfx-lg{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  flex-shrink:0;
  object-fit:contain;
  color:var(--text);
}

.gfx-md{width:34px;height:34px;}
.gfx-lg{width:46px;height:46px;}

.site-logo{
  width:46px;
  height:46px;
  object-fit:contain;
  flex-shrink:0;
}

@media (max-width:768px){
  .site-nav{height:72px;padding:0 16px;}
  .site-nav-brand{font-size:30px;}
  .site-logo{width:34px;height:34px;}
  .nav-close-btn{display:none !important;}
}

/* Below the general mobile breakpoint, the brand text + logo + 3 nav
   icon buttons + all the gaps/padding between them add up to ~386px —
   fine down to ~375px-wide phones (confirmed no overflow there), but
   narrower ones (e.g. a Galaxy S25 FE at 360px) don't have room, and
   since .site-nav has no flex-wrap, the excess silently overflows off
   the right edge instead of wrapping. Scoped tightly to 370px (not
   390px, as an earlier pass did) so this ONLY kicks in for phones that
   actually need it — 375px+ devices keep full-size everything. */
@media (max-width:370px){
  .site-nav{gap:10px; padding:0 12px;}
  .site-nav-brand{font-size:23px; gap:9px;}
  .site-logo{width:26px;height:26px;}
  .nav-right{gap:6px;}
  .nav-lang-btn, .nav-theme-btn, .nav-share-btn{width:32px;height:32px;}
}


footer{
  text-align:center;
  padding:32px 24px;
  font-size:13px;
  background:#1d2436;
  color:var(--text);
}

html[data-theme="light"] footer{
  background:#d4dbee;
}

.footer-dashboard{
  border-top:1px solid rgba(255,255,255,.1);
  padding:48px 24px 8px;
  display:flex;
  justify-content:center;
  background:#1d2436;
}

html[data-theme="light"] .footer-dashboard{
  background:#d4dbee;
}

.footer-dashboard-inner{
  width:100%;
  max-width:820px;
  margin:0 auto;
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(260px, 1fr));
  gap:16px;
}

.footer-dashboard-col{
  display:flex;
  flex-direction:column;
  gap:10px;
}

.footer-dashboard-col h3,
.footer-getting-started-group h3{
  color:var(--text);
  font-size:13px;
  font-weight:900;
  text-transform:uppercase;
  letter-spacing:.04em;
  margin:0 0 4px;
}

/* One "Getting started with" heading over both tool columns — same
   grid item as any other .footer-dashboard-col, just with the tools
   split into two side-by-side lists underneath a single shared title
   instead of the heading belonging to (and only visually sitting
   above) the first column alone. */
.footer-getting-started-group{
  display:flex;
  flex-direction:column;
  gap:10px;
}
.footer-getting-started-columns{
  display:flex;
  gap:16px;
}

@media (max-width:768px){
  .footer-dashboard-inner{
    grid-template-columns:repeat(2, 1fr);
    gap:10px;
  }
  .footer-getting-started-group{
    display:none;
  }
}

.footer-dash-link{
  background:none;
  border:none;
  padding:0;
  color:var(--text);
  font-size:13px;
  text-align:left;
  text-decoration:none;
  cursor:pointer;
  font-family:inherit;
  width:fit-content;
}

.footer-dash-link:hover{
  color:var(--text);
  text-decoration:underline;
}

/* Company-column footer links have a playful "alien" wording (Our
   Universe, Galactic Handbook, etc.) on desktop, but plain labels
   (About Us, Terms of Use, etc.) on mobile — same two-span,
   CSS-swapped-by-breakpoint pattern as Context's toolbar labels. */
.footer-link-plain{
  display:none;
}

@media (max-width:768px){
  .footer-link-fun{
    display:none;
  }
  .footer-link-plain{
    display:inline;
  }
}

.footer-dash-text{
  color:var(--text);
  opacity:.6;
  font-size:13px;
}

#footerContactSection .footer-dash-text{
  opacity:1;
}

.footer-contact-address{
  display:none; /* markup kept for later use */
}

.footer-dash-text a{
  opacity:1;
  color:#4da6ff;
  font-weight:700;
  text-decoration:underline;
  text-underline-offset:2px;
}

.footer-dash-text a:hover{
  color:#7cc0ff;
}

footer a{
  color:var(--text);
}


.nav-close-btn{
  color:var(--text);
  display:none;
  align-items:center;
  justify-content:center;
  width:36px;
  height:36px;
  border:1px solid var(--border);
  border-radius:10px;
  background:none;
  line-height:1;
  cursor:pointer;
  font-family:inherit;
  transition:.2s;
}

.nav-close-btn svg{
  width:20px;
  height:20px;
}

.nav-close-btn.visible{
  display:flex;
}

/* ===== LANGUAGE DROPDOWN ===== */
/* Hidden site-wide for now — staying English-only until translations are
   ready to turn back on. The underlying i18n (data-i18n attrs, cs/pl
   dictionaries, bcApplyLang etc. in shared/site.js) is untouched, so
   flipping this back to visible is the only step needed to re-enable
   language switching later. index.html doesn't load this stylesheet
   (see the top of this file) so it carries the same rule in its own
   inline <style>. */
.nav-lang-wrap{
  display:none;
  position:relative;
}

.nav-lang-btn{
  width:36px;
  height:36px;
  padding:0;
  border:1px solid var(--border);
  border-radius:10px;
  background:none;
  color:var(--text);
  cursor:pointer;
  font-family:inherit;
  transition:.2s;
  display:flex;
  align-items:center;
  justify-content:center;
}

.nav-lang-btn svg{
  width:20px;
  height:20px;
  flex-shrink:0;
}

.nav-lang-btn:hover{
  border-color:var(--border-strong);
}

.nav-lang-menu{
  position:absolute;
  top:44px;
  right:0;
  width:150px;
  padding:8px;
  border-radius:18px;
  background:#1C2436;
  border:1px solid rgba(255,255,255,.14);
  display:none;
  gap:6px;
  z-index:60;
}

.nav-lang-menu.open{
  display:grid;
}

.nav-lang-menu button{
  height:42px;
  padding:0 12px;
  border-radius:12px;
  border:0;
  background:transparent;
  color:#ffffff;
  font-size:15px;
  font-weight:700;
  text-align:left;
  cursor:pointer;
}

.nav-lang-menu button:hover{
  background:rgba(255,255,255,.08);
}

.nav-lang-menu button.active{
  color:var(--accent2);
}

.nav-close-btn:hover{
  color:var(--text);
  border-color:var(--border-strong);
}


.tool-drop{
  margin-top:24px;
  padding:56px 24px;
  border-radius:28px;
  border:2px dashed var(--border-strong);
  background:transparent;
  text-align:center;
  cursor:pointer;
  transition:.25s;
  font-size:22px;
  font-weight:800;
  color:var(--text);
}

.tool-drop:hover{
  border-color:var(--accent);
  transform:scale(1.01);
}

.tool-drop.active{
  border-color:var(--accent);
  background:rgba(255,255,255,.06);
}

.tool-continue-btn{
  display:block;
  width:100%;
  margin-top:14px;
  box-sizing:border-box;
}
.tool-continue-btn[hidden]{ display:none; }

/* Mobile shortens the label — "Continue where you left off" is long
   enough to wrap awkwardly on a phone-width button; "Continue editing"
   says the same thing in less space. Desktop keeps the full phrase.
   Compound .tool-primary-btn.tool-continue-btn selector (both classes
   the button actually carries) rather than .tool-continue-btn alone —
   equal-specificity .tool-primary-btn{font-size:20px} is defined later
   in this file and was winning the cascade, showing both the real text
   AND the ::before text concatenated instead of hiding the former. */
@media (max-width:768px){
  .tool-primary-btn.tool-continue-btn{
    font-size:0;
  }
  .tool-primary-btn.tool-continue-btn::before{
    content:"Continue editing";
    font-size:20px;
  }
}

#page-convert .tool-drop.active{
  border-color:#7626f5;
  background:rgba(118,38,245,.1);
}

#page-compress .tool-drop.active{
  border-color:#30c4ff;
  background:rgba(48,196,255,.1);
}


.tool-controls{
  display:grid;
  grid-template-columns:1fr 1.2fr;
  gap:20px;
  margin-top:24px;
  align-items:stretch;
}

#page-convert .tool-controls{
  grid-template-columns:1.6fr 1fr;
}

@media (max-width:768px){
  .tool-controls{grid-template-columns:1fr;}
  #page-convert .tool-controls{grid-template-columns:1fr;}
  .tool-format-btn{display:none !important;}
  .tool-format-select{display:block !important;}
}

.tool-format-buttons{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(90px, 1fr));
  gap:12px;
}

/* Desktop only — hidden ≤768px in favor of .tool-format-select.
   Compress's quality-level cards (Low/Medium/High, .compress-level-btn
   used to be a hand-copied near-duplicate of this exact block) now
   just add the .tool-format-btn class alongside their own — padding
   and line-height here accommodate its two-line label, and
   span.level-sub is its optional description line, unused by anything
   else that uses this base class. */
.tool-format-btn{
  height:74px;
  padding:0 12px;
  border-radius:26px;
  border:1px solid var(--border-strong);
  background:transparent;
  color:var(--text);
  font-size:18px;
  font-weight:800;
  line-height:1.1;
  cursor:pointer;
  transition:.2s;
}

.tool-format-btn:hover{
  border-color:var(--border-strong);
  background:rgba(127,127,127,.1);
}

.tool-format-btn:focus-visible{
  outline:2px solid rgba(255,255,255,.5);
  outline-offset:2px;
}

html[data-theme="dark"] .tool-format-btn:focus-visible{
  outline-color:rgba(0,0,0,.4);
}

/* .35/.5 read fine as "selected" against a deep, saturated banner
   (Convert's purple) but nearly vanished against a pale, high-luminance
   one (Compress's light blue) — translucent white blended into a
   light background reads as almost no fill at all, so "Low" looked
   indistinguishable from the unselected pills next to it. Strong
   enough opacity here to read as a real filled pill regardless of how
   light the tool's own brand color happens to be. */
.tool-format-btn.active{
  background:rgba(255,255,255,.65);
  color:#1d2436;
  border-color:rgba(255,255,255,.9);
}

html[data-theme="dark"] .tool-format-btn.active{
  background:rgba(0,0,0,.28);
  border-color:rgba(0,0,0,.4);
  color:var(--text);
}

.tool-format-btn span.level-sub{
  display:none;
}

/* Mobile only — shown ≤768px in favor of .tool-format-btn */
.tool-format-select{
  display:none;
  width:100%;
  height:74px;
  padding:0 24px;
  border-radius:26px;
  border:1px solid var(--border-strong);
  background-color:transparent;
  color:var(--text);
  font-size:20px;
  font-weight:800;
  font-family:inherit;
  text-align:center;
  text-align-last:center;
  cursor:pointer;
  transition:.2s;
  -webkit-appearance:none;
  -moz-appearance:none;
  appearance:none;
}

.tool-format-select:hover{
  border-color:var(--border-strong);
  background:rgba(127,127,127,.1);
}

/* The select itself already follows the theme via var(--text)/
   transparent background above — but a native <option> list can't take
   a translucent/transparent background (it needs to be opaque to stay
   legible against arbitrary OS popup chrome), so it needs its own
   explicit light/dark pair instead of reusing the shared tokens
   directly. This was hardcoded to the dark pair only, which is why the
   dropdown list always rendered dark regardless of site theme — same
   navy used by .tool-preview-modal for the dark case, so it fits the
   rest of the site's dark palette rather than inventing a new color. */
.tool-format-select option{
  background:#fff;
  color:#000;
}
html[data-theme="dark"] .tool-format-select option{
  background:#1d2436;
  color:#fff;
}

.tool-primary-btn{
  height:74px;
  padding:0 32px;
  border-radius:26px;
  border:1px solid rgba(255,255,255,.5);
  cursor:pointer;
  font-weight:900;
  font-size:20px;
  background:rgba(255,255,255,.35);
  color:var(--text);
  transition:.2s;
}

.tool-primary-btn:hover{
  border-color:rgba(255,255,255,.65);
  background:rgba(255,255,255,.45);
}

.tool-primary-btn:focus-visible{
  outline:2px solid rgba(255,255,255,.5);
  outline-offset:2px;
}

.tool-primary-btn:disabled{
  cursor:not-allowed;
  transform:none;
  background:rgba(255,255,255,.2);
}

html[data-theme="dark"] .tool-primary-btn{
  border:1px solid rgba(0,0,0,.4);
  background:rgba(0,0,0,.28);
}

html[data-theme="dark"] .tool-primary-btn:focus-visible{
  outline-color:rgba(0,0,0,.4);
}

html[data-theme="dark"] .tool-primary-btn:hover{
  border-color:rgba(0,0,0,.55);
  background:rgba(0,0,0,.36);
}

html[data-theme="dark"] .tool-primary-btn:disabled{
  background:rgba(0,0,0,.14);
}

.tool-status{
  color:var(--text);
  margin-top:22px;
  min-height:24px;
  font-size:12px;
  font-weight:700;
  font-family:monospace;
}

/* Terminal-style "> " prefix on any status message (ready/progress/
   done/error) — CSS-only, so it applies to every tool automatically
   without touching each translated string. */
.tool-status:not(:empty)::before{
  content:"> ";
  font-weight:700;
}

/* ===== Shared typography — .bc-label / .bc-heading / .bc-body =====
   Every tool independently grew its own small-caps "eyebrow" label
   (Convert's .tool-io-label, Colorfy's .colorfy-palette-heading — same
   13px/800/uppercase/letter-spaced recipe, hand-copied with slightly
   different values each time) and Coudio's "Output format"/"Bitrate"
   never got styled at all, just a bare <label>. These three classes are
   the shared alternative — add one alongside whatever local class still
   holds genuinely tool-specific layout (margin, flex, text-align), the
   same split every other shared component in this file uses.
   .bc-label   — small uppercase eyebrow above a control (a dropdown
                 group, a setting). .tool-io-label/.colorfy-palette-
                 heading now extend this rather than repeating it.
   .bc-heading — a real section heading inside a tool banner (Colorfy's
                 "Saved colors" is an <h3>, not just a label — same
                 visual weight as .bc-label but semantically a heading,
                 kept distinct so screen readers still get real heading
                 structure, not a mislabeled <span>).
   .bc-body    — normal-weight banner body text (a helper line, a short
                 instruction) at the tool's own text color/opacity,
                 for anything that isn't the drop-zone prompt
                 (.tool-drop) or the terminal-style status line
                 (.tool-status), both already shared above. */
.bc-label,
.bc-heading{
  font-size:13px;
  font-weight:800;
  letter-spacing:.04em;
  text-transform:uppercase;
  color:var(--text);
  opacity:.7;
}
.bc-body{
  color:var(--text);
  opacity:.8;
  font-size:14px;
  line-height:1.5;
}

.tool-results{
  margin-top:24px;
  display:flex;
  gap:14px;
  overflow-x:auto;
  padding-bottom:8px;
  scroll-behavior:smooth;
  scrollbar-width:thin;
}

.tool-results::-webkit-scrollbar{
  height:8px;
}

.tool-results::-webkit-scrollbar-thumb{
  background:rgba(255,255,255,.25);
  border-radius:8px;
}

.tool-results:empty{
  display:none;
}

.tool-results .result{
  flex:0 0 160px;
}

/* The shared "loaded file" card core — every tool that lists files it
   has loaded builds on this (Convert/Compress/Congify/Coudio/Context
   via this class directly; Cleanly/Combine via their own
   .exif-file-item/.combine-file-item, which now add this class rather
   than repeating the same background/border/transition — see each of
   those files' own comment). Used to be a near-invisible
   rgba(...,.03) tint regardless of which tool used it, so Convert and
   Compress each grew their own much bolder per-tool override just to
   make the card actually read — this is that bolder recipe promoted to
   the actual shared default, same light/dark flip formula as every
   on-banner control. A tool can still layer a brand-tinted border on
   top (see #page-convert .result below) without needing to redeclare
   the background too. */
.result{
  position:relative;
  background:rgba(255,255,255,.35);
  border:1px solid rgba(255,255,255,.5);
  border-radius:16px;
  padding:10px;
  font-size:15px;
  transition:background .2s, border-color .2s;
}
html[data-theme="dark"] .result{
  background:rgba(0,0,0,.25);
  border-color:rgba(0,0,0,.4);
}

.nav-right{
  display:flex;
  align-items:center;
  gap:8px;
}

.nav-exit-group{
  display:flex;
  align-items:center;
  gap:8px;
  margin-left:24px;
}

.nav-share-wrap{
  position:relative;
}

.nav-share-btn,
.nav-theme-btn{
  color:var(--text);
  width:36px;
  height:36px;
  padding:0;
  border:1px solid var(--border);
  border-radius:10px;
  background:none;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  transition:.2s;
  font-family:inherit;
}

.nav-share-btn:hover,
.nav-theme-btn:hover{
  color:var(--text);
  border-color:var(--border-strong);
}

.nav-theme-btn svg{
  width:20px;
  height:20px;
}

.nav-share-icon{
  width:20px;
  height:20px;
  fill:none;
  stroke:currentColor;
  stroke-width:2.15;
  stroke-linecap:round;
  stroke-linejoin:round;
}

.nav-share-menu{
  position:absolute;
  top:44px;
  right:0;
  width:190px;
  padding:8px;
  border-radius:18px;
  background:#1d2436;
  border:1px solid rgba(255,255,255,.14);
  display:none;
  gap:2px;
  z-index:60;
}

.nav-share-menu.open{
  display:grid;
}

.nav-share-menu button{
  height:34px;
  padding:0 12px;
  border-radius:12px;
  border:0;
  background:transparent;
  color:#ffffff;
  font-size:15px;
  font-weight:700;
  text-align:left;
  cursor:pointer;
}

.nav-share-menu button:hover{
  background:rgba(255,255,255,.08);
}

.nav-share-priority{
  margin-bottom:4px;
}

.nav-share-more-toggle{
  display:flex !important;
  align-items:center;
  justify-content:center;
  height:22px !important;
  padding:0 !important;
  width:100%;
  justify-self:stretch;
  color:rgba(255,255,255,.7) !important;
}

.nav-share-more-arrow{
  display:inline-block;
  font-size:11px;
  transition:transform .2s ease;
}

.nav-share-more-toggle[aria-expanded="true"] .nav-share-more-arrow{
  transform:rotate(180deg);
}

.nav-share-more-list:not([hidden]){
  display:grid;
  gap:2px;
}

@keyframes copy-toast-blink{
  0%, 100%{ opacity:1; }
  50%{ opacity:0; }
}

/* .result/.tool-results ship dark-only in the SPA (no light override
   existed there either) — added here since a brand-new standalone page
   should render correctly in light mode from the start. */
html[data-theme="light"] .tool-results::-webkit-scrollbar-thumb{
  background:rgba(0,0,0,.25);
}

/* ===== Generic page hero (About/FAQ/Terms/Privacy/Cookies/etc) ===== */
.hero{
  text-align:center;
  padding:40px 0 56px;
}

.hero h1{
  margin:0 0 18px;
  font-size:clamp(41px, 5.2vw, 63px);
  line-height:1.1;
  letter-spacing:-0.03em;
}


.page-heading-mobile{ display:none; }

.hero p.page-alias{
  text-align:center;
}

@media (max-width:768px){
  .page-heading-desktop{ display:none; }
  .page-heading-mobile{ display:block; }
  .page-alias{ display:none; }
}

.hero p{
  margin:0 auto 16px;
  max-width:700px;
  font-size:clamp(17px, 1.8vw, 19px);
  line-height:1.6;
  text-align:left;
}

/* ===== Engine-status-card (decorative terminal-style panel), reused
   by About's banner and (later) the mainpage loading banner ===== */
.engine-status-card{
  position:relative;
  margin:32px auto 0;
  max-width:680px;
  text-align:left;
  background:#1d2436;
  border:1px solid rgba(255,255,255,.14);
  border-radius:16px;
  overflow:hidden;
  font-family:"Courier New", Courier, monospace;
  letter-spacing:.02em;
}

html[data-theme="light"] .engine-status-card{
  background:#e4e9f5;
  border-color:rgba(29,36,54,.3);
}

.engine-status-title{
  margin-left:6px;
  font-size:15px;
  font-weight:700;
  color:#e5e7eb;
  opacity:.8;
}

html[data-theme="light"] .engine-status-title{
  color:#1d2436;
}

.engine-status-body{
  padding:16px;
  display:flex;
  flex-direction:column;
  gap:8px;
  position:relative;
}

/* Genuinely hidden (not just blurred behind an overlay) until the
   yellow dot is clicked — matches "minimize/restore" better than the
   old blur-and-click-a-button-on-top pattern, and reuses the same
   traffic-light dots already styled for the cookie-settings mock
   window elsewhere on the site instead of a bespoke reveal control. */
/* Scoped by #id, not the shared .engine-status-card class — that class
   is also reused purely for its look by the "loading other tools"
   banner, which has no header/dots and never gets a "revealed" class,
   so a class-based rule here hid its entire body permanently, leaving
   just its empty bordered box (reported as "now all I see is a
   line"). */
#engineStatusCard:not(.revealed) .engine-status-body{
  display:none;
}

.engine-status-dot-toggle{
  padding:0;
  border:none;
  cursor:pointer;
  /* Same 8px circle as the plain decorative dots either side of it —
     button reset alone would otherwise shrink it to fit its (empty)
     text content. */
  width:8px;
  height:8px;
}

.engine-status-dot-toggle:hover,
.engine-status-dot-toggle:focus-visible{
  box-shadow:0 0 0 3px rgba(250,204,21,.35);
  outline:none;
}

.engine-status-row{
  font-size:15px;
  font-weight:700;
  color:#e5e7eb;
  opacity:.8;
  white-space:pre-wrap;
}

html[data-theme="light"] .engine-status-row{
  color:#1d2436;
}

.engine-status-value{
  color:#4ade80;
  font-weight:700;
}

html[data-theme="light"] .engine-status-value{
  color:#16a34a;
}

.engine-status-error{
  color:#ff6b6b;
  font-weight:700;
}

html[data-theme="light"] .engine-status-error{
  color:#dc2626;
}

.backlog-coms-row{
  white-space:normal;
  line-height:1.5;
}

.backlog-coms-sender{
  font-weight:800;
}

.backlog-coms-meta{
  display:block;
  font-size:11px;
  font-weight:700;
  letter-spacing:.05em;
  opacity:.55;
  margin-bottom:2px;
}

/* ===== Legal-page article styling (Terms/Privacy/Cookies) ===== */
.terms-article{
  max-width:900px;
  margin:0 auto;
  padding:0 24px 80px;
  text-align:left;
}

.terms-updated{
  color:var(--text);
  opacity:.7;
  font-size:15px;
  margin:0 0 28px;
}

.terms-article p{
  color:var(--text);
  margin:0 0 14px;
  font-size:clamp(17px, 1.8vw, 19px);
  line-height:1.7;
}

.terms-article h2{
  color:var(--text);
  font-size:clamp(28px, 3.6vw, 40px);
  margin:36px 0 12px;
}

.terms-article h2:first-of-type{
  margin-top:0;
}

.terms-article ul{
  margin:0 0 16px;
  padding-left:22px;
  color:var(--text);
  font-size:clamp(17px, 1.8vw, 19px);
  line-height:1.7;
}

.terms-article a{
  color:#4da6ff;
  font-weight:700;
  text-decoration:underline;
  text-underline-offset:2px;
  cursor:pointer;
}

.terms-article a:hover{
  color:#7cc0ff;
}

.terms-article li{
  margin-bottom:8px;
}

/* ===== Tool card shell — colored banner behind a tool's controls.
   Give #page-<id> (or whatever the tool's outer .tool-app carries as an
   id) its own background via ::before, e.g. #page-gif::before{...}. ===== */
.tool-wrap{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:48px 18px 80px;
}

.tool-app{
  position:relative;
  width:1100px;
  max-width:94vw;
  min-height:402px;
  border-radius:36px;
  padding:36px;
  box-sizing:border-box;
}
.tool-app::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:-1;
  border-radius:36px;
}

/* ===== Tool shell (wrap/app/header), reused by every tool page.
   Brand background color (.tool-app::before) is set per-page, not here. */
.tool-wrap{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:48px 18px 80px;
}

.tool-app{
  position:relative;
  width:1100px;
  max-width:94vw;
  min-height:402px;
  border-radius:36px;
  padding:36px;
  box-sizing:border-box;
}
.tool-app::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:-1;
  border-radius:36px;
}

.tool-header{
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap:16px;
  flex-wrap:wrap;
  margin-bottom:8px;
}

.tool-logo{
  display:flex;
  align-items:center;
  gap:15px;
  font-size:28px;
  font-weight:900;
  color:var(--text);
}

.tool-logo svg{
  width:34px;
  height:34px;
}

/* Live "safe & private" check badge — hidden until a real check has
   actually run (see startPrivacyCheck/finishPrivacyCheck), so it never
   claims something unverified. Intentionally uncolored/plain, not a
   colored trust-badge, matching the terminal aesthetic used elsewhere. */
.privacy-check-badge{
  display:none;
  font-family:monospace;
  font-size:12px;
  font-weight:700;
  color:var(--text);
  white-space:nowrap;
}

.privacy-check-badge.visible{
  display:inline-block;
}

/* ===== Ad slot wrapper, reused by every page with an ad ===== */
.ad-slot{
  max-width:820px;
  margin:0 auto 32px;
  padding:0 24px;
  text-align:center;
  overflow:hidden;
}

.ad-slot-banner{
  margin:24px auto;
}

/* ===== Content-section wrapper (tool explainer articles below each
   tool app), reused by every tool page. Per-tool cs-shape color is
   set in each page's own <style> block, not here. ===== */
/* ===== SEO CONTENT COMPONENTS CONVERT ===== */
.content-section-convert{
  position:relative;
  max-width:900px;
  margin:0 auto;
  padding:60px 24px;
}

.content-section-article-wrap{
  position:relative;
  padding-top:8px;
}

.content-section-bg{
  position:absolute;
  inset:0;
  z-index:0;
  overflow:visible;
  pointer-events:none;
}

.content-section-article-wrap > *:not(.content-section-bg),
.content-section-format-wrap > *:not(.content-section-bg){
  position:relative;
  z-index:1;
}

.content-section-format-wrap{
  position:relative;
}

.content-section-format-wrap .cs-shape-2{
  top:auto;
  bottom:-60px;
  right:2%;
  width:190px;
  height:220px;
}

.cs-shape{
  position:absolute;
  display:block;
  border-radius:24px;
  opacity:.22;
  filter:blur(1px);
  animation:mp-colors-drift 26s cubic-bezier(.45,0,.55,1) infinite;
}

.cs-shape-1{ top:-40px; left:-60px; width:245px; height:286px; animation-name:mp-colors-drift-x; animation-duration:30s; }
.cs-shape-2{ top:20%; right:-70px; width:245px; height:286px; animation-delay:-5s; }
.cs-shape-3{ bottom:-40px; left:30%; width:200px; height:230px; animation-name:mp-colors-drift-up; animation-delay:0s; }

.content-section-convert[data-tool="convert"] .cs-shape{ background:#d670ff; }
.content-section-compress[data-tool="compress"] .cs-shape{ background:#68e1ff; }
.content-section-convert[data-tool="combine"] .cs-shape{ background:#ec6f63; }
.content-section-convert[data-tool="exif"] .cs-shape{ background:#4ade80; }
.content-section-convert[data-tool="context"] .cs-shape{ background:#ffde89; }
.content-section-convert[data-tool="gif"] .cs-shape{ background:#22D3D0; }

.content-section-convert[data-tool="convert"] .cs-shape-3,
.content-section-compress[data-tool="compress"] .cs-shape-3{ bottom:40px; }

@media (max-width:768px){
  .cs-shape{ opacity:.16; }
  .cs-shape-1{ width:208px; height:243px; left:-40px; }
  /* Three floating shapes felt like too much on a small screen — down
     to two on mobile (this was also the one that used to bleed past
     the right edge before the site-wide overflow-x:hidden fix). */
  .cs-shape-2{ display:none; }
  .cs-shape-3{ width:170px; height:196px; }
}

.content-section-convert h2{
  margin:0 0 14px;
  font-size:clamp(28px, 3.6vw, 40px);
  letter-spacing:-0.02em;
  text-align:center;
}

.content-section-convert h2.content-section-subheading{
  margin-top:10px;
  padding-top:0;
  border-top:none;
}

.content-section-convert h3{
  margin:32px 0 14px;
  font-size:clamp(28px, 3.6vw, 40px);
  letter-spacing:-0.02em;
  text-align:center;
  color:var(--text);
}

.content-section-convert > p.lead{
  color:var(--text);
  margin:0 auto 32px;
  max-width:680px;
  text-align:center;
  font-size:clamp(17px, 1.8vw, 19px);
  line-height:1.7;
}

.golden-rules-link{
  display:block;
  margin:24px auto 0;
  background:none;
  border:none;
  padding:0;
  color:var(--accent2);
  font-family:inherit;
  font-size:15px;
  font-weight:600;
  text-align:center;
  text-decoration:underline;
  text-underline-offset:3px;
  cursor:pointer;
}

.golden-rules-link-inline{
  color:var(--accent2);
  font-weight:600;
  text-decoration:underline;
  text-underline-offset:3px;
  cursor:pointer;
}

.golden-rules-link-inline:hover,
.golden-rules-link-inline:focus-visible{
  color:var(--text);
}

.golden-rules-link:hover,
.golden-rules-link:focus-visible{
  color:var(--text);
}

/* ===== Cleanly-specific (exif) tool CSS ===== */
/* ===== EXIF STRIPPER TAB ===== */
.exif-file-list{
  display:flex;
  flex-direction:column;
  gap:10px;
  margin-top:20px;
}

/* Flips light/dark same as every on-banner control — see "On-banner
   controls flip with theme" in shared/site.css's header comment. */
/* Background/border-width/transition now come from .result (this
   file, above) — added as a second class on the markup
   (class="exif-file-item result") rather than repeated here, same
   split as Convert's own .result border-color override. This only
   keeps the row layout and Cleanly's brand-tinted border, the two
   genuinely tool-specific pieces .result has no opinion on. */
.exif-file-item{
  display:flex;
  align-items:center;
  gap:14px;
  padding:12px 16px;
  border-radius:14px;
  border-color:#4ade8055;
}

.exif-file-thumb{
  flex-shrink:0;
  width:56px;
  height:56px;
  border-radius:10px;
  overflow:hidden;
  background:rgba(255,255,255,.08);
}

.exif-file-thumb img{
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
}

.exif-file-info{
  flex:1;
  min-width:0;
}

.exif-file-name{
  font-weight:700;
  font-size:15px;
  color:var(--text);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  transition:color .2s;
}

.exif-file-size{
  font-size:15px;
  color:var(--text);
  opacity:.8;
  margin-bottom:6px;
}

.exif-tags{
  display:flex;
  flex-wrap:wrap;
  gap:6px;
}

.exif-tag{
  font-size:15px;
  font-weight:700;
  padding:4px 10px;
  border-radius:999px;
  background:rgba(255,255,255,.35);
  color:var(--text);
  transition:background .2s, color .2s;
}
html[data-theme="dark"] .exif-tag{
  background:rgba(0,0,0,.3);
}

/* Not an actual found-metadata tag like its siblings — just a status
   line reusing .exif-tag's row/font for layout consistency — so it
   drops the pill chrome (background/padding/radius) that only makes
   sense for something you'd click or that represents one of several
   distinct items. color:var(--text) at full opacity — same shared
   token .exif-file-name (the filename right above it) uses, so the two
   lines read at identical weight/brightness instead of one being a
   one-off literal. */
.exif-tag-clean{
  padding:0;
  border-radius:0;
  background:none;
  color:var(--text);
}
/* html[data-theme="dark"] .exif-tag (above) outranks a plain
   .exif-tag-clean on specificity — .exif-tag-clean alone isn't enough
   to actually clear the background in dark theme, it silently lost to
   that rule. Matching specificity here, same trap as the .result
   card's own light/dark override earlier. */
html[data-theme="dark"] .exif-tag-clean{
  background:none;
}

.exif-scan-note{
  margin-top:6px;
  font-size:12px;
  color:var(--text);
  opacity:.75;
}

/* .exif-file-remove's own visual recipe now lives in shared
   .bc-file-remove-btn (below, near .bc-remove-btn) — added as a
   second class on the markup (class="exif-file-remove
   bc-file-remove-btn"). Kept as a class only as an addressing hook
   for its own JS listener. */

/* Full-width at every size now, matching Convert's Download button
   (a .tool-primary-btn sitting directly in .tool-controls, a grid,
   whose items stretch to fill their column by default) — this one used
   to only stretch full-width ≤768px via the mobile override below,
   staying a small right-aligned pill on desktop otherwise. */
.exif-actions{
  display:flex;
  justify-content:stretch;
  margin-top:24px;
}
.exif-actions .tool-primary-btn{
  width:100%;
}

/* ===== .content-section-convert p (missed earlier) ===== */
.content-section-convert p{
  color:var(--text);
  font-size:clamp(17px, 1.8vw, 19px);
  line-height:1.7;
}

/* ===== format-pick comparison groups (Not sure which X to use?) ===== */
.format-pick-groups{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(170px, 1fr));
  gap:24px;
  text-align:left;
  max-width:1200px;
  width:calc(100vw - 48px);
  position:relative;
  left:50%;
  transform:translateX(-50%);
}

.format-pick-name{
  margin:0 0 8px;
  color:var(--text);
  font-size:clamp(17px, 1.8vw, 19px);
  font-weight:700;
}

/* Emoji live here, not in translated strings — one definition covers
   every language, and .fmt-icon is already listed in the light-theme
   invert-cancel selector above so colors stay correct in both themes. */
.fmt-icon{
  display:inline-block;
}

.fmt-icon-jpg::before{ content:"📷"; }
.fmt-icon-png::before{ content:"🖼️"; }
.fmt-icon-webp::before{ content:"🚀"; }
.fmt-icon-svg::before{ content:"📐"; }
.fmt-icon-heic::before{ content:"📱"; }
.fmt-icon-pdf::before{ content:"📄"; }
.fmt-icon-pros::before{ content:"👍"; }
.fmt-icon-cons::before{ content:"⚠️"; }
.fmt-icon-low::before{ content:"🔍"; }
.fmt-icon-medium::before{ content:"⚖️"; }
.fmt-icon-high::before{ content:"🪶"; }

.format-pick-sublist{
  margin:0;
  padding:0;
  list-style:none;
  display:flex;
  flex-direction:column;
  gap:6px;
}

.format-pick-sublist li{
  color:var(--text);
  font-size:clamp(17px, 1.8vw, 19px);
  line-height:1.5;
  opacity:.85;
  padding-left:16px;
  position:relative;
}

.format-pick-sublist li::before{
  content:"•";
  position:absolute;
  left:0;
  opacity:.6;
}

/* .compress-level-btn is now the shared .tool-format-btn (above) —
   this used to be a hand-copied near-duplicate of that exact recipe,
   plus the two properties (padding, line-height) now folded into the
   base class itself. Only the 3-column grid layout stays here, since
   that's genuinely specific to a fixed 3-option choice. */
.compress-level-buttons{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:12px;
}

.selected-compression{
  margin-top:10px;
  color:var(--text);
  font-size:12px;
  font-weight:700;
  font-family:monospace;
}

.selected-compression:not(:empty)::before{
  content:"> ";
  font-weight:700;
}

/* ===== result card remove/name/size (shared by Compress/Convert/etc) ===== */
.result-remove{
  position:absolute;
  top:6px;
  right:6px;
  width:24px;
  height:24px;
  border-radius:50%;
  border:none;
  background:rgba(0,0,0,.55);
  color:#fff;
  font-size:15px;
  line-height:1;
  cursor:pointer;
  opacity:0;
  transition:opacity .15s ease, background .15s ease;
  z-index:2;
}

.result:hover .result-remove{
  opacity:1;
}

.result-remove:hover{
  background:rgba(0,0,0,.8);
}

.result img{
  width:100%;
  height:90px;
  object-fit:cover;
  border-radius:10px;
  margin-bottom:8px;
}

.result.result-pdf img{
  object-fit:contain;
  background:rgba(0,0,0,.18);
}

.result.result-svg img{
  object-fit:contain;
  background:rgba(0,0,0,.18);
}

.result-name{
  color:var(--text);
  font-weight:700;
  word-break:break-all;
  transition:color .2s;
}

.result-size{
  color:var(--text);
  margin-top:2px;
}

/* ===== .bc-combo — shared searchable dropdown pattern =====
   The reusable version of the site's various one-off .xx-dropdown
   components (Congify's .gif-dropdown, Coudio's .cd-dropdown, etc) —
   the label lives inside an actual text input (typing filters the
   list, for dropdowns long enough that scanning gets old), the active
   option gets a filled checkmark instead of just a bold/highlighted
   row, and any option can carry a small badge (e.g. "New") on its
   right edge. Reach for this over a one-off dropdown whenever a tool
   needs a list much longer than 4-5 items. Markup:
     <div class="bc-combo" id="...">
       <div class="bc-combo-trigger" aria-haspopup="listbox" aria-expanded="false">
         <input class="bc-combo-input" readonly>
         <span class="bc-combo-chevron" aria-hidden="true"></span>
       </div>
       <div class="bc-combo-menu" role="listbox" hidden>
         <button class="bc-combo-option active" data-value="..." data-label="..." role="option" aria-selected="true">
           <span>Label</span>
           <span class="bc-combo-option-check" aria-hidden="true">✓</span>
         </button>
         ...
       </div>
     </div>
   Used to be a fixed translucent-black trigger / dark navy menu
   regardless of site theme, on the reasoning that it always sits on a
   tool's own saturated banner. In practice that read as "stuck in dark
   mode" once light theme existed (Convert's IN/OUT pills were the
   report that caught it) — it now follows .tool-primary-btn's flip
   pattern instead: light-tint trigger/menu by default, dark-tint under
   html[data-theme="dark"], same as everything else that sits on a
   banner and needs real contrast in both themes. */
.bc-combo{
  position:relative;
}
.bc-combo-trigger{
  display:flex;
  align-items:center;
  gap:8px;
  width:100%;
  height:40px;
  padding:0 12px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,.5);
  background:rgba(255,255,255,.35);
  cursor:pointer;
  transition:.2s;
}
.bc-combo-trigger:hover,
.bc-combo-trigger[aria-expanded="true"]{
  background:rgba(255,255,255,.45);
}
html[data-theme="dark"] .bc-combo-trigger{
  border-color:rgba(0,0,0,.4);
  background:rgba(0,0,0,.25);
}
html[data-theme="dark"] .bc-combo-trigger:hover,
html[data-theme="dark"] .bc-combo-trigger[aria-expanded="true"]{
  background:rgba(0,0,0,.35);
}
.bc-combo-input{
  flex:1;
  min-width:0;
  border:none;
  background:none;
  outline:none;
  color:var(--text);
  font-family:inherit;
  font-size:14px;
  font-weight:700;
  padding:0;
  cursor:pointer;
}
.bc-combo-trigger[aria-expanded="true"] .bc-combo-input{
  cursor:text;
}
.bc-combo-input::placeholder{
  color:var(--text);
  opacity:.5;
  font-weight:600;
}
.bc-combo-chevron{
  width:6px;
  height:6px;
  border-right:1.5px solid currentColor;
  border-bottom:1.5px solid currentColor;
  color:var(--text);
  opacity:.75;
  transform:rotate(45deg);
  transition:transform .15s;
  flex-shrink:0;
}
.bc-combo-trigger[aria-expanded="true"] .bc-combo-chevron{
  transform:rotate(225deg);
}
.bc-combo-menu{
  position:absolute;
  top:calc(100% + 6px);
  left:0;
  width:100%;
  max-height:280px;
  overflow-y:auto;
  z-index:6;
  padding:6px;
  border-radius:14px;
  border:1px solid rgba(29,36,54,.3);
  background:#e4e9f5;
  display:flex;
  flex-direction:column;
  gap:2px;
}
html[data-theme="dark"] .bc-combo-menu{
  border-color:rgba(255,255,255,.16);
  background:#1d2436;
}
.bc-combo-menu[hidden]{
  display:none;
}
.bc-combo-option{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  height:38px;
  padding:0 12px;
  border:none;
  border-radius:9px;
  background:transparent;
  color:#1d2436;
  font-family:inherit;
  font-size:14px;
  font-weight:600;
  text-align:left;
  cursor:pointer;
}
.bc-combo-option:hover{
  background:rgba(29,36,54,.08);
}
.bc-combo-option.active{
  background:rgba(29,36,54,.1);
}
html[data-theme="dark"] .bc-combo-option{
  color:#fff;
}
html[data-theme="dark"] .bc-combo-option:hover{
  background:rgba(255,255,255,.1);
}
html[data-theme="dark"] .bc-combo-option.active{
  background:rgba(255,255,255,.08);
}
.bc-combo-option[hidden]{
  display:none;
}
.bc-combo-option-check{
  display:none;
  width:18px;
  height:18px;
  border-radius:50%;
  background:#1d2436;
  color:#fff;
  align-items:center;
  justify-content:center;
  font-size:11px;
  font-weight:900;
  flex-shrink:0;
}
html[data-theme="dark"] .bc-combo-option-check{
  background:#fff;
  color:#1d2436;
}
.bc-combo-option.active .bc-combo-option-check{
  display:flex;
}
.bc-combo-option-badge{
  padding:2px 8px;
  border-radius:6px;
  background:#facc15;
  color:#1d2436;
  font-size:11px;
  font-weight:800;
  flex-shrink:0;
}
.bc-combo-empty{
  padding:10px 12px;
  color:var(--text);
  opacity:.6;
  font-size:13px;
}
.bc-combo-empty[hidden]{
  display:none;
}

/* ===== .bc-dropdown — shared NON-searchable dropdown (JS:
   bcRegisterDropdown in this file) ===== a plain trigger button (label
   + chevron, no text input) opening a menu of buttons — for short
   option lists where search adds nothing. Originated in Congify as
   .gif-dropdown; Coudio and Colorfy used to hand-roll visually
   identical copies under their own prefixes (.cd-dropdown,
   .colorfy-format-dropdown) — this is that one component, shared.
   Flips light/dark same as .bc-combo above (see that block's comment
   for why — it used to be a fixed dark trigger/menu regardless of
   theme, which read as a real bug in light mode). */
.bc-dropdown{
  position:relative;
}
.bc-dropdown-trigger{
  display:flex;
  align-items:center;
  gap:8px;
  width:100%;
  height:40px;
  padding:0 12px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,.5);
  background:rgba(255,255,255,.35);
  color:var(--text);
  font-family:inherit;
  font-size:14px;
  font-weight:700;
  cursor:pointer;
  transition:.2s;
}
.bc-dropdown-trigger:hover,
.bc-dropdown-trigger[aria-expanded="true"]{
  background:rgba(255,255,255,.45);
}
html[data-theme="dark"] .bc-dropdown-trigger{
  border-color:rgba(0,0,0,.4);
  background:rgba(0,0,0,.25);
}
html[data-theme="dark"] .bc-dropdown-trigger:hover,
html[data-theme="dark"] .bc-dropdown-trigger[aria-expanded="true"]{
  background:rgba(0,0,0,.35);
}
.bc-dropdown-trigger-label{
  flex:1;
  min-width:0;
  text-align:center;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
/* .bc-dropdown-trigger-lg — 74px variant, for a trigger standing next
   to other 74px controls (.tool-primary-btn, .tool-format-select on
   mobile) instead of a normal 40px settings-row pill. Add as a second
   class alongside .bc-dropdown-trigger; everything but size/type stays
   inherited from the base rule. Originated on Convert's Input/Output
   pickers. */
.bc-dropdown-trigger-lg{
  height:74px;
  padding:0 20px;
  border-radius:26px;
  font-size:18px;
  font-weight:800;
}
/* Thin outline chevron (a rotated border-corner, not a filled glyph) —
   same shape as .bc-combo-chevron, so every dropdown/select across the
   site reads as the same control. currentColor already follows the
   trigger's own color:var(--text), so no separate theme rule needed. */
.bc-dropdown-chevron{
  width:6px;
  height:6px;
  border-right:1.5px solid currentColor;
  border-bottom:1.5px solid currentColor;
  opacity:.75;
  transform:rotate(45deg);
  flex-shrink:0;
}
/* ===== .option-change-btn — single-button cycling picker =====
   For a short, ORDERED list of values where "click to advance" reads
   better than opening a menu (fps steps, playback speed, anything on a
   numeric ladder) — a lighter alternative to .bc-dropdown-trigger for
   when there's no real "browse the options" need, just "bump to the
   next one." One click = one step forward, wrapping back to the first
   option after the last. Same size/shape/flip formula as
   .bc-dropdown-trigger (so it sits flush next to real dropdowns in a
   settings row) with the chevron swapped for a small cycle-arrows glyph
   in place of the "opens a menu" affordance, since nothing opens here.
   Register via bcRegisterOptionChangeBtn (shared/site.js) — don't
   hand-roll the click-to-advance logic per tool. */
.option-change-btn{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  width:100%;
  height:40px;
  padding:0 12px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,.5);
  background:rgba(255,255,255,.35);
  color:var(--text);
  font-family:inherit;
  font-size:14px;
  font-weight:700;
  cursor:pointer;
  transition:.2s;
}
.option-change-btn:hover{
  background:rgba(255,255,255,.45);
}
html[data-theme="dark"] .option-change-btn{
  border-color:rgba(0,0,0,.4);
  background:rgba(0,0,0,.25);
}
html[data-theme="dark"] .option-change-btn:hover{
  background:rgba(0,0,0,.35);
}
.option-change-btn-label{
  flex:1;
  min-width:0;
  text-align:center;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
/* Three stacked horizontal lines (cycle/ladder affordance) — distinct
   from .bc-dropdown-chevron's single "opens downward" arrow, since
   clicking here doesn't open a menu, it just steps to the next rung on
   the ladder. Three bars drawn as background layers rather than
   pseudo-elements — only two pseudo-elements are available per element,
   one short of the three lines needed. Same 1.5px stroke weight/opacity
   as the rest of the site's outline glyphs (.bc-dropdown-chevron etc.). */
.option-change-btn-icon{
  width:14px;
  height:10px;
  flex-shrink:0;
  opacity:.75;
  background-image:
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor);
  background-size:100% 1.5px;
  background-repeat:no-repeat;
  background-position:0 0, 0 50%, 0 100%;
}

/* ===== .bc-color-dot — plain preset-swatch dot =====
   A CSS-only colored circle, no <input> involved — for a trigger/option
   that just displays a color, background painted via inline style or
   JS (bcSetColorSwatch above). Originated as two byte-for-byte
   duplicate copies, Context's .context-color-dot and Congify's
   .gif-dropdown-dot; both now point here, added as a second class on
   their markup, with the tool-local class kept only as an
   addressing/JS hook the way .cf-color-trigger etc. are. */
.bc-color-dot{
  display:inline-block;
  width:14px;
  height:14px;
  border-radius:50%;
  border:1px solid rgba(255,255,255,.4);
  flex-shrink:0;
}

/* ===== .bc-color-picker-input — invisible full-cover native picker =====
   For a trigger that needs a genuinely custom color (not one of a
   fixed preset list — Codify's screenshot-background control is the
   reference), pair a real <input type="color"> using this class with a
   plain .bc-color-dot as the trigger's visible swatch — update the
   dot's background from the input's own "input" event.
   Markup contract (trigger needs position:relative, its own class):
     <label class="... your-trigger-class" style="position:relative">
       <span class="bc-color-dot" style="background:#...;" aria-hidden="true"></span>
       <span>Label text</span>
       <input type="color" class="bc-color-picker-input" value="#..." aria-label="...">
     </label>

   This used to instead scale the <input> up and clip it down with
   overflow:hidden into a small visible swatch (kept as this file's own
   .bc-color-swatch). That approach turned out unfixable properly: even
   once its display:inline bug was patched, the *visible* swatch color
   people saw was the browser's own native rendering of the input's
   internal swatch — a second, independent paint from whatever a JS-set
   .style.background on a sibling dot showed, so the two could disagree,
   and Safari/older Chromium versions have inconsistent clip behavior
   for a scaled-up color input regardless. Making the input fully
   invisible instead sidesteps all of that: nothing about the visible
   color depends on how (or whether) the browser lets you clip its
   native picker chrome — the dot is just a normal, always-reliable CSS
   circle, and the input's only job is to be a full-size, always-there
   click target that opens the OS picker. */
.bc-color-picker-input{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  margin:0;
  padding:0;
  border:none;
  background:none;
  opacity:0;
  cursor:pointer;
}
.bc-dropdown-menu{
  position:absolute;
  top:calc(100% + 6px);
  left:0;
  width:100%;
  z-index:5;
  padding:6px;
  border-radius:18px;
  border:1px solid rgba(29,36,54,.3);
  background:#e4e9f5;
  display:flex;
  flex-direction:column;
  gap:2px;
}
html[data-theme="dark"] .bc-dropdown-menu{
  border-color:rgba(255,255,255,.16);
  background:#1d2436;
}
.bc-dropdown-menu[hidden]{
  display:none;
}
.bc-dropdown-option{
  display:flex;
  align-items:center;
  gap:10px;
  height:36px;
  padding:0 10px;
  border:none;
  border-radius:18px;
  background:transparent;
  color:#1d2436;
  font-family:inherit;
  font-size:14px;
  text-align:left;
  cursor:pointer;
}
.bc-dropdown-option:hover{
  background:rgba(29,36,54,.08);
}
.bc-dropdown-option.active{
  background:rgba(29,36,54,.12);
  font-weight:700;
}
html[data-theme="dark"] .bc-dropdown-option{
  color:#fff;
}
html[data-theme="dark"] .bc-dropdown-option:hover{
  background:rgba(255,255,255,.1);
}
html[data-theme="dark"] .bc-dropdown-option.active{
  background:rgba(255,255,255,.14);
}

/* ===== .bc-toggle-btn — shared pressed/unpressed pill button =====
   Originated in Context (.context-style-btn, its Bold/Italic/Underline
   row); Congify's own comment said it copied "Context's .context-tool-btn/
   .context-style-btn/.context-color-trigger/.context-color-menu" for its
   caption toolbar — this is that one recipe, shared. No shared JS: the
   actual toggle logic (what a press does, which element it restyles) is
   different enough per use that a `btn.classList.toggle(...)` one-liner
   in each tool's own file is simpler than a forced abstraction. Flips
   light/dark same as .bc-dropdown/.bc-combo above — every on-banner
   button follows this one formula now, see "On-banner controls flip
   with theme" in this file's header comment. */
.bc-toggle-btn{
  padding:0 14px;
  height:40px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,.5);
  background:rgba(255,255,255,.35);
  color:var(--text);
  font-family:inherit;
  font-size:15px;
  font-weight:700;
  cursor:pointer;
  transition:.2s;
}
.bc-toggle-btn:hover{
  background:rgba(255,255,255,.45);
}
.bc-toggle-btn.active,
.bc-toggle-btn[aria-pressed="true"]{
  background:rgba(255,255,255,.6);
  border-color:#1d2436;
}
.bc-toggle-btn:disabled{
  opacity:.45;
  cursor:not-allowed;
}
.bc-toggle-btn:disabled:hover{
  background:rgba(255,255,255,.35);
}
html[data-theme="dark"] .bc-toggle-btn{
  border-color:rgba(0,0,0,.4);
  background:rgba(0,0,0,.25);
}
html[data-theme="dark"] .bc-toggle-btn:hover{
  background:rgba(0,0,0,.35);
}
html[data-theme="dark"] .bc-toggle-btn.active,
html[data-theme="dark"] .bc-toggle-btn[aria-pressed="true"]{
  background:rgba(0,0,0,.5);
  border-color:#fff;
}
html[data-theme="dark"] .bc-toggle-btn:disabled:hover{
  background:rgba(0,0,0,.25);
}
/* Modifier for an icon-only square button (B/I/U-style single glyph)
   instead of the padded text/label pill above. */
.bc-toggle-btn-icon{
  width:34px;
  padding:0;
  display:flex;
  align-items:center;
  justify-content:center;
}
.bc-toggle-btn-group{
  display:flex;
  align-items:center;
  gap:6px;
}

/* ===== .bc-editor-input — shared on-banner text editor surface =====
   Codify's code textarea is currently the only editor-style input on
   the site, but it was still a private .cf-code-input recipe rather
   than a shared class — the kind of setup that let its :hover state go
   un-migrated when every other on-banner control got the light/dark
   flip (it kept a hardcoded dark hover fill regardless of theme, so
   hovering the editor in light theme flashed a dark overlay — that's
   what prompted pulling this out for real instead of just patching the
   one bug). Covers only the theme-dependent chrome (border/background/
   color/placeholder/hover/focus/scrollbar) — size, padding, font, and
   resize behavior stay local to whatever uses it, same split as
   .bc-toggle-btn/.bc-resize-handle. Add this class alongside a local
   one (`class="cf-code-input bc-editor-input"`) rather than
   hand-rolling the chrome again for the next tool that needs an
   editor-style input. */
.bc-editor-input{
  border:1px solid rgba(255,255,255,.5);
  background:rgba(255,255,255,.35);
  color:var(--text);
  transition:background .2s, border-color .2s, color .2s;
  scrollbar-width:none;
  -ms-overflow-style:none;
}
.bc-editor-input::-webkit-scrollbar{
  display:none;
}
.bc-editor-input::placeholder{
  color:var(--text);
  opacity:.5;
}
.bc-editor-input:hover{
  background:rgba(255,255,255,.45);
}
.bc-editor-input:focus{
  outline:none;
}
html[data-theme="dark"] .bc-editor-input{
  border-color:rgba(0,0,0,.4);
  background:rgba(0,0,0,.25);
}
html[data-theme="dark"] .bc-editor-input:hover{
  background:rgba(0,0,0,.32);
}

/* ===== .bc-resize-handle — shared drag-to-resize circle =====
   Originated in Context (an inline-<svg> <span>, JS-created per text/
   signature box); Congify, Codify, and Colorfy each independently
   copied the same circle+arrow visual as a CSS ::before icon on a
   static button/span instead — every one of those tools' own comments
   named which prior tool they copied it from. This shares the common
   geometry (size, shape, color, border, touch-action) that was
   byte-identical across all four; position offset and cursor direction
   differ per use (a corner-anchored frame vs. an inline text box) and
   stay as local overrides on top of this. Works with either icon
   technique — an inline <svg> child (sized below) or a ::before
   background-image — since neither is this class's concern. */
.bc-resize-handle{
  position:absolute;
  width:21px;
  height:21px;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:50%;
  background:#2563eb;
  border:2px solid #fff;
  touch-action:none;
  z-index:4;
}
.bc-resize-handle svg{
  width:13px;
  height:13px;
  pointer-events:none;
}

/* ===== .bc-remove-btn — shared red "×" circle remove button =====
   Just the shared visual: circle shape, red fill/border, hover shade.
   Size (width/height/font-size) and position (absolute vs inline,
   offsets) stay local per use since those genuinely differ — a small
   badge on a saved-color chip needs different geometry than a 28px
   button pinned to a banner's corner. Originated independently in
   Colorfy, Congify, Context, and Coudio (each tool's own file-remove
   button, plus two more sizes inside Colorfy) — all six now point at
   this one shared base. */
.bc-remove-btn{
  padding:0;
  border-radius:50%;
  border:1px solid #b91c3c;
  background:#e11d48;
  color:#fff;
  font-weight:900;
  line-height:1;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
}
.bc-remove-btn:hover{
  background:#b91c3c;
}

/* ===== .bc-file-remove-btn — shared translucent "×" circle on a
   file-item row (distinct from .bc-remove-btn's bold red circle,
   used for small badges) — a plain on-banner control, same
   light/dark flip formula as .bc-combo-trigger etc. Originated
   independently in Cleanly (.exif-file-remove) and Combine
   (.combine-file-remove), byte-identical to each other; both now
   point at this one shared class. ===== */
.bc-file-remove-btn{
  flex-shrink:0;
  width:28px;
  height:28px;
  border-radius:50%;
  border:none;
  background:rgba(255,255,255,.35);
  color:var(--text);
  font-size:16px;
  line-height:1;
  cursor:pointer;
  transition:.2s;
}
html[data-theme="dark"] .bc-file-remove-btn{
  background:rgba(0,0,0,.3);
}
.bc-file-remove-btn:hover{
  background:rgba(255,255,255,.5);
}
html[data-theme="dark"] .bc-file-remove-btn:hover{
  background:rgba(0,0,0,.5);
}

/* ===== .bc-url-row — shared "or paste a link" URL-load row =====
   Originated in Congify, Coudio hand-copied an identical version under
   its own prefix — both now point at this one. Tool-specific bits
   (placeholder text, aria-label, the actual load/paste logic) stay in
   each tool's own markup/JS; this only covers the shared visual. */
.bc-url-row{
  position:relative;
  z-index:1;
  max-width:480px;
  margin:8px auto 0;
}
.bc-url-divider{
  display:flex;
  align-items:center;
  gap:10px;
  margin-bottom:12px;
  color:var(--text);
  opacity:.65;
  font-size:13px;
  font-weight:700;
}
.bc-url-divider span:not(:only-child){
  flex:1;
  height:1px;
  background:rgba(29,36,54,.2);
}
html[data-theme="dark"] .bc-url-divider span:not(:only-child){
  background:rgba(255,255,255,.25);
}
.bc-url-form{
  display:flex;
  gap:8px;
}
/* Flips light/dark same as .bc-dropdown/.bc-combo/.bc-toggle-btn above
   — see "On-banner controls flip with theme" in this file's header
   comment. */
.bc-url-input{
  flex:1;
  min-width:0;
  height:40px;
  padding:0 14px;
  border-radius:20px;
  border:1px solid rgba(255,255,255,.5);
  background:rgba(255,255,255,.35);
  color:var(--text);
  font-family:inherit;
  font-size:14px;
  font-weight:600;
  transition:.2s;
}
.bc-url-input::placeholder{
  color:var(--text);
  opacity:.55;
  font-weight:600;
}
.bc-url-input:focus{
  outline:none;
  border-color:#1d2436;
}
html[data-theme="dark"] .bc-url-input{
  border-color:rgba(0,0,0,.4);
  background:rgba(0,0,0,.25);
}
html[data-theme="dark"] .bc-url-input:focus{
  border-color:#fff;
}
.bc-url-btn{
  flex-shrink:0;
  width:auto;
  padding:0 20px;
  height:40px;
  border-radius:20px;
  font-size:14px;
}
.bc-url-status{
  margin-top:10px;
  font-size:13px;
  color:var(--text);
  opacity:.85;
  text-align:center;
}
.bc-url-status[hidden]{ display:none; }

/* Mobile-only Paste button — a phone keyboard's paste affordance is
   easy to miss on a URL-type field, so mobile gets an explicit button.
   Reflows to two rows so Input/Paste/Load never squeezes onto one
   cramped line. */
.bc-url-paste-btn{ display:none; }
@media (max-width:768px){
  .bc-url-form{ flex-wrap:wrap; }
  .bc-url-input{ flex:1 1 100%; }
  .bc-url-paste-btn{ display:block; flex:1; }
  .bc-url-btn{ flex:1; }
}

