/* UnixClock — "Precision Utility" design system
   Tokens first, then layout, then components. Keep this file the single source of
   truth for spacing/colour so tool pages never need their own stylesheet.

   The visual language is instrumentation, not marketing: hierarchy comes from
   1px outlines and tonal fills rather than from elevation, blue is reserved for
   things you can interact with, and numeric data is set in a monospace face so
   digits hold their column as they tick. */

:root {
  --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  /* JetBrains Mono for timestamps, offsets and coordinates. Listed first but not
     downloaded: a webfont on 1,456 pages is a third-party request and a render
     delay this site does not otherwise carry. Self-host the two families into
     /fonts and add @font-face here if you want them guaranteed. */
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --blue-50:#eff5ff; --blue-100:#dbe8fe; --blue-500:#3b82f6; --blue-600:#2570eb; --blue-700:#1d5ed1;
  /* Slate, per the design system's neutral ramp. */
  --gray-0:#ffffff; --gray-25:#fcfdff; --gray-50:#f8fafc; --gray-75:#f1f5f9; --gray-100:#eef2f7; --gray-200:#e2e8f0;
  --gray-300:#cbd5e1; --gray-350:#b6c2d2; --gray-400:#94a3b8; --gray-500:#64748b; --gray-600:#475569; --gray-700:#334155;
  --gray-800:#1e293b; --gray-900:#0f172a;

  --accent:var(--blue-500);
  --accent-strong:var(--blue-600);
  --accent-soft:var(--blue-50);
  --success:#0f7a5a; --success-soft:#e6f6f0;
  --warning:#b26205; --warning-soft:#fdf3e3;
  --danger:#c02626;  --danger-soft:#fdecec;

  --bg:var(--gray-0);
  /* Deeper than --surface on purpose: at gray-50 a white tile sat at 1.05
     contrast against the page and read as flat text, not as a box. */
  --bg-alt:var(--gray-100);
  --surface:var(--gray-0);
  --surface-alt:var(--gray-50);
  --border:var(--gray-200);
  --border-strong:var(--gray-300);
  --border-stronger:var(--gray-350);
  --accent-ring:rgba(59,130,246,.35);
  /* Time is data, not a call to action, so it takes the text colour. Blue stays
     reserved for interactive elements. One token to change if you disagree. */
  --clock:var(--text);
  --clock-sec:var(--text-mute);
  --text:var(--gray-900);
  --text-soft:var(--gray-600);
  --text-mute:var(--gray-500);

  /* Disciplined and geometric: 4px on controls, 8px on the containers that
     group them. Anything rounder starts to read as consumer software. */
  --radius:4px;
  --radius-lg:8px;
  /* Deliberately almost nothing. Surfaces are separated by outline and fill;
     only genuinely floating things (menus, the date picker) cast at all. */
  --shadow-sm:0 1px 2px rgba(15,23,42,.06);
  --shadow:0 2px 4px rgba(15,23,42,.05);
  --shadow-lg:0 4px 12px rgba(15,23,42,.08);
  --maxw:1280px;
  --gap:16px;
  /* The height of the DESKTOP header row, and nothing more. Below 900px
     .header-in wraps the search box onto a second row and switches to
     height:auto, so anything that has to sit under the header must derive its
     offset from the header box itself rather than from this token. */
  --header-h:56px;
  /* The header's bottom rule. Shared with the drawer, which hangs from the
     header's border edge: a percentage offset on an absolutely positioned box
     stops at the containing block's padding box, one border width short. */
  --header-line:1px;
}

/* The palette inverts around slate: surfaces move to #0f172a and text to
   #f8fafc, keeping the high-contrast "instrument" feel rather than going soft. */
html[data-theme="dark"] {
  --bg:#0f172a; --bg-alt:#0b1220; --surface:#131c30; --surface-alt:#1b2639;
  --border:#28344a; --border-strong:#3a485f; --border-stronger:#4d5d76;
  --text:#f8fafc; --text-soft:#c3cddb; --text-mute:#94a3b8;
  --accent:#60a5fa; --accent-strong:#93c5fd; --accent-soft:#17253d;
  --accent-ring:rgba(96,165,250,.4);
  --clock:var(--text);
  --clock-sec:var(--text-mute);
  --success:#34d399; --success-soft:#0d2a22;
  --warning:#fbbf24; --warning-soft:#2c2410;
  --danger:#f87171;  --danger-soft:#2f1719;
  --shadow-sm:0 1px 2px rgba(0,0,0,.45);
  --shadow:0 2px 4px rgba(0,0,0,.5);
  --shadow-lg:0 4px 14px rgba(0,0,0,.55);
}

*,*::before,*::after { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
/* The UA rule behind [hidden] only covers the HTML namespace, so a hidden
   <svg> stays visible. Restating it as an author rule fixes every namespace. */
[hidden] { display:none; }
body {
  margin:0; font-family:var(--font-sans); font-size:16px; line-height:1.55;
  color:var(--text); background:var(--bg-alt);
  -webkit-font-smoothing:antialiased;
}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto} *{animation:none!important;transition:none!important} }

/* Type scale from the design system: headline-lg 32/40 at -0.01em, headline-md
   24/32, body-md 16/24. Tightened tracking on the largest sizes only. */
h1,h2,h3,h4 { margin:0 0 .5em; font-weight:600; letter-spacing:-.01em; }
h1{font-size:2rem;line-height:2.5rem}
h2{font-size:1.5rem;line-height:2rem}
h3{font-size:1.125rem;line-height:1.75rem}
h4{font-size:1rem;line-height:1.5rem;font-weight:650}
p{margin:0 0 1em}
a{color:var(--accent-strong); text-decoration:none}
a:hover{text-decoration:underline}
ul,ol{margin:0 0 1em; padding-left:1.25em}
li{margin:.25em 0}
small{font-size:.85rem}
code,kbd{font-family:var(--font-mono); font-size:.9em}
kbd{background:var(--surface-alt);border:1px solid var(--border);border-bottom-width:2px;border-radius:4px;padding:1px 5px;font-size:.8em}
hr{border:0;border-top:1px solid var(--border);margin:24px 0}
img,svg{max-width:100%;height:auto}

:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }

/* Hidden until focused. Clipped rather than pushed off-canvas: a negative
   `left` is harmless in LTR but extends the scrollable area in an RTL document,
   which gave every RTL page thousands of pixels of phantom horizontal scroll. */
.skip-link{
  position:absolute;top:8px;inset-inline-start:8px;
  width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;
  background:var(--accent);color:#fff;padding:8px 14px;border-radius:var(--radius);z-index:200
}
.skip-link:focus{width:auto;height:auto;clip:auto;clip-path:none}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 16px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- header ---------- */
.site-header{position:sticky;top:0;z-index:50;background:var(--surface);border-bottom:var(--header-line) solid var(--border)}
.header-in{display:flex;align-items:center;gap:12px;height:var(--header-h);max-width:var(--maxw);margin:0 auto;padding:0 16px}
/* The lockup is one inline SVG drawn from src/brand.js. Its "Time" half is
   currentColor, so the link's colour is what carries it into dark mode. */
.logo{display:flex;align-items:center;color:var(--text);flex:none}
.logo:hover{text-decoration:none}
.logo-lockup{display:block;height:30px;width:auto}
/* Nav sits centred between the wordmark and the utilities. min-width is
   max-content rather than 0 because a centred flex line whose content does not
   fit spills past BOTH edges: with min-width:0 the nav shrank below its items,
   and from 901px to 1134px the first link was painted over the wordmark (18px
   into it at 1100px) and the last one under the search box. Holding the nav at
   its content width makes the search box, which can shrink, absorb the
   squeeze instead. The drawer below resets it. */
.nav{display:flex;align-items:center;justify-content:center;gap:2px;flex:1;min-width:max-content}
.nav a,.nav button.navlink{
  font-size:.9rem;color:var(--text-soft);padding:7px 9px;border-radius:var(--radius);
  background:none;border:0;font-family:inherit;cursor:pointer;white-space:nowrap
}
.nav a:hover,.nav button.navlink:hover{background:var(--surface-alt);color:var(--text);text-decoration:none}
.nav a[aria-current="page"]{color:var(--accent-strong);background:var(--accent-soft)}
.header-actions{display:flex;align-items:center;gap:6px;flex:none}
.icon-btn{
  display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;
  border:1px solid var(--border);background:var(--surface);border-radius:var(--radius);
  color:var(--text-soft);cursor:pointer;padding:0
}
.icon-btn:hover{background:var(--surface-alt);color:var(--text)}
/* flex:none so an icon can never be squashed narrower than its box. */
.icon-btn svg{width:17px;height:17px;flex:none}
.nav-toggle{display:none}
.has-sub{position:relative}
.submenu{
  position:absolute;top:calc(100% + 6px);left:0;min-width:210px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  padding:6px;display:none;z-index:60
}
.submenu.open{display:block}
.submenu a{display:block;padding:7px 10px;font-size:.9rem;border-radius:var(--radius);color:var(--text-soft)}

@media (max-width:900px){
  /* The drawer hangs off the header BOX, never off --header-h. That token is
     the desktop row height; here .header-in wraps and stands 110.8px tall at
     375px, so a fixed drawer offset by 56px began 54.8px *underneath* the
     header — and with .site-header at z-index:50 over a z-index:auto drawer,
     the first item, World Clock again, was completely covered: a tap on it
     landed on #site-search-input. Scrolling could not save it either, since it
     sat above scrollTop:0. position:absolute hands the containing block to the
     sticky header, so the offset is whatever the header actually wrapped to at
     any width — the same trick .lang-switch uses further down. --header-line
     makes up the border width a percentage falls short by, at both ends.

     justify-content must be reset alongside the direction. The desktop rule
     centres the row, and a centred flex container whose content overflows
     spills equally past BOTH edges — but only the bottom half can be scrolled
     to. Inherited here it put the first ~690px of the drawer, World Clock
     included, permanently above scrollTop:0 and out of reach.

     min-width:0 likewise undoes the desktop max-content floor: the drawer is a
     full-width column, and a floor sized to its widest label would push it off
     the side of a narrow screen. */
  .nav{position:absolute;top:calc(100% + var(--header-line));inset-inline:0;
       background:var(--surface);border-bottom:1px solid var(--border);
       flex-direction:column;align-items:stretch;justify-content:flex-start;gap:0;padding:8px;margin:0;display:none;
       max-height:calc(100vh - 100% - var(--header-line));overflow:auto;min-width:0}
  .nav.open{display:flex}
  .nav a,.nav button.navlink{padding:11px 12px;font-size:1rem;text-align:left;width:100%}
  .nav-toggle{display:inline-flex}
  /* Submenus inside the drawer flatten into the stack. Scoped to .nav on
     purpose: the language switcher sits in .header-actions, outside the
     drawer, and must stay a popover or it expands the header permanently. */
  .nav .submenu{position:static;display:block;border:0;box-shadow:none;padding:0 0 6px 12px;min-width:0;background:none}
  .nav .submenu a{font-size:.92rem}
}

/* ---------- search ---------- */
.search{position:relative;flex:1;max-width:340px;margin-left:auto}
/* The [type="search"] qualifier is load-bearing: the generic form-control block
   further down also matches this input with equal specificity, and being later
   it would win the cascade and flatten the left padding the icon sits in. */
.search input[type="search"]{
  width:100%;height:34px;padding:0 10px 0 30px;font:inherit;font-size:.9rem;color:var(--text);
  background:var(--surface-alt);border:1px solid var(--border);border-radius:var(--radius)
}
.search .s-icon{position:absolute;left:9px;top:9px;width:16px;height:16px;color:var(--text-mute);pointer-events:none}
.search-results{
  position:absolute;top:calc(100% + 6px);left:0;right:0;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);max-height:60vh;overflow:auto;display:none;z-index:70;padding:4px
}
.search-results.open{display:block}
.search-results li{list-style:none;margin:0}
.search-results ul{margin:0;padding:0}
.search-results a{display:flex;gap:10px;align-items:center;padding:8px 10px;border-radius:var(--radius);color:var(--text)}
.search-results a:hover,.search-results a.active{background:var(--accent-soft);text-decoration:none}
.sr-kind{font-size:.72rem;color:var(--text-mute);border:1px solid var(--border);border-radius:99px;padding:1px 7px;flex:none}
.sr-sub{color:var(--text-mute);font-size:.8rem}
.search-empty{padding:14px;color:var(--text-mute);font-size:.9rem}
/* flex:0 0 100% is the part that matters. The desktop rule's flex:1 sets
   flex-basis:0%, and a flex basis beats width for the main size — so with only
   width:100% the box shrank to whatever was left on the first row (93px at
   375px wide) instead of wrapping to a row of its own. */
@media (max-width:900px){
  .search{order:3;flex:0 0 100%;max-width:none;width:100%;margin:0}
  .header-in{flex-wrap:wrap;height:auto;padding-top:8px;padding-bottom:8px}
  /* Touch targets: 34px is fine for a pointer, too small for a thumb. */
  .header-actions .icon-btn{width:44px;height:44px}
}

/* ---------- the header between its two layouts ----------
   901–1279px is where the desktop header is real but cramped. At full size the
   wordmark, six nav items, a 340px search box and two icons need 1159px before
   they all fit — 1282px in Portuguese, the longest catalogue — so in this range
   the nav tightens and the search box gives up width instead of anything
   overlapping. Nothing here applies at 1280px and up, and the drawer owns
   everything at 900px and below. English is the only published catalogue and
   fits all the way down to 901px; Portuguese, Spanish and French would not,
   with Portuguese still overflowing the row below ~919px, so publishing
   another locale means re-measuring this range and probably moving the
   drawer breakpoint up for it.

   Range syntax rather than (min-width:901px): viewport widths are fractional on
   a scaled display, where a 901px window measures 900.8px and matches neither
   (max-width:900px) nor (min-width:901px) — the header would drop back to the
   full-size rules in exactly the range that has no room for them. `900px <
   width` is the drawer query's exact complement. */
@media (900px < width < 1280px) {
  .header-in{gap:8px}
  .nav a,.nav button.navlink{padding:7px 6px}
  /* The box bottoms out around 130px at 901px, too narrow to read a result in,
     so the panel keeps its own width and hangs from the inline-end edge, which
     is the side with room in both directions. */
  .site-header .search-results{inset-inline-start:auto;width:max(100%,340px)}
}

/* ---------- page scaffold ---------- */
main{display:block;padding:20px 0 48px}
.breadcrumb{font-size:.83rem;color:var(--text-mute);margin:0 0 12px}
.breadcrumb ol{list-style:none;display:flex;flex-wrap:wrap;gap:6px;margin:0;padding:0}
.breadcrumb li::after{content:"/";margin-left:6px;color:var(--border-strong)}
.breadcrumb li:last-child::after{content:""}
.page-head{margin-bottom:18px}
.page-head p.lede{color:var(--text-soft);max-width:70ch;margin:0}

/* No shadow by design — a card is defined by its outline, and the page reads as
   a set of panels in an instrument rather than sheets floating over a desk. */
.card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:20px
}
.card + .card{margin-top:16px}
.section{margin-top:32px}
.section h2{margin-bottom:.6em}

.grid{display:grid;gap:var(--gap)}
.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:860px){ .cols-3,.cols-4{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:560px){ .cols-2,.cols-3,.cols-4{grid-template-columns:1fr} }

/* ---------- forms ----------
   A .field is a three-row stack — label / control / hint — and .form-row makes
   those rows line up across every item in the row via subgrid. Without that the
   row can only bottom-align whole fields, so one wrapping hint drags its
   neighbour's input out of line with it. Buttons opt into the same grid by
   sitting on the control row. */
.field{display:grid;grid-template-rows:auto auto auto;row-gap:5px;min-width:0}
.field label,.lbl{
  font-size:.75rem;font-weight:600;line-height:1rem;color:var(--text-soft);align-self:end;
  text-transform:uppercase;letter-spacing:.05em
}
input[type=text],input[type=number],input[type=date],input[type=time],input[type=month],
input[type=week],input[type=search],input[type=datetime-local],select,textarea{
  width:100%;font:inherit;font-size:.95rem;color:var(--text);background:var(--surface);
  border:1px solid var(--border-strong);border-radius:var(--radius);padding:8px 10px;min-height:38px;
  /* Date-family controls size themselves to their native text otherwise, which
     left the month fields visibly narrower than every neighbouring input. */
  appearance:none;-webkit-appearance:none;
  /* min-width:auto is the grid/flex default and beats width:100%, so a month
     input would refuse to shrink below its native text width and push the page
     into horizontal scroll on a phone. */
  min-width:0
}
select{
  cursor:pointer;padding-inline-end:32px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7383' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-size:16px;background-position:right 9px center
}
/* ---------- chips / lists ---------- */
.chips{display:flex;flex-wrap:wrap;gap:6px;padding:0;margin:0;list-style:none}
.chip{
  display:inline-flex;align-items:center;gap:6px;font-size:.85rem;padding:3px 9px;
  border:1px solid var(--border);border-radius:2px;background:var(--surface-alt);color:var(--text-soft)
}
a.chip:hover{border-color:var(--accent);color:var(--accent-strong);text-decoration:none}
.chip button{background:none;border:0;cursor:pointer;color:var(--text-mute);padding:0;font-size:1rem;line-height:1}
.link-list{list-style:none;padding:0;margin:0;columns:2;column-gap:24px}
@media (max-width:560px){ .link-list{columns:1} }
.link-list li{margin:.3em 0;break-inside:avoid}

/* ---------- faq ---------- */
.faq details{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);padding:0;margin-bottom:8px}
.faq summary{cursor:pointer;padding:11px 14px;font-weight:600;font-size:.95rem;list-style:none;display:flex;justify-content:space-between;gap:10px}
.faq summary::-webkit-details-marker{display:none}
/* The question is a real heading for parsers that weight heading tags; it must
   not look like one, so it inherits the summary's own type. */
.faq summary h3{margin:0;font:inherit;flex:1;min-width:0}
.faq summary::after{content:"+";color:var(--text-mute);font-weight:400}
.faq details[open] summary::after{content:"−"}
.faq .a{padding:0 14px 12px;color:var(--text-soft);font-size:.93rem}
.faq .a p:last-child{margin-bottom:0}

/* ---------- footer ---------- */
.site-footer{background:var(--surface);border-top:1px solid var(--border);padding:32px 0 20px;margin-top:auto}
.footer-grid{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}
.footer-grid h3{font-size:.78rem;text-transform:uppercase;letter-spacing:.07em;color:var(--text-mute);margin-bottom:.7em}
.footer-grid ul{list-style:none;padding:0;margin:0}
.footer-grid li{margin:.35em 0}
.footer-grid a{color:var(--text-soft);font-size:.9rem}
.footer-bottom{margin-top:24px;padding-top:14px;border-top:1px solid var(--border);display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:.83rem;color:var(--text-mute)}
.link-btn{background:none;border:0;padding:0;font:inherit;color:var(--accent-strong);cursor:pointer}
.link-btn:hover{text-decoration:underline}

/* ---------- consent ---------- */
.consent{
  position:fixed;left:12px;right:12px;bottom:12px;z-index:140;max-width:760px;margin:0 auto;
  display:flex;align-items:center;justify-content:space-between;gap:12px 16px;flex-wrap:wrap;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  padding:14px 16px;font-size:.9rem
}
/* Sets a display of its own after the bare [hidden] rule, which would otherwise lose. */
.consent[hidden]{display:none}
.consent p{margin:0;flex:1 1 300px}
.consent-actions{display:flex;gap:8px;flex:1 1 auto;justify-content:flex-end}
@media (max-width:560px){ .consent-actions .btn{flex:1} }

/* ---------- ads / upsell ---------- */
.ad-slot{border:1px dashed var(--border);border-radius:var(--radius);padding:10px;text-align:center;color:var(--text-mute);font-size:.75rem;background:var(--surface-alt);margin:22px 0}
.ad-slot[hidden]{display:none}
.upsell{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;background:var(--accent-soft);border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px;font-size:.9rem;margin-top:24px}

/* ---------- toast ---------- */
.toast{
  position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(8px);opacity:0;pointer-events:none;
  background:var(--gray-900);color:#fff;padding:9px 16px;border-radius:99px;font-size:.88rem;z-index:200;transition:opacity .16s,transform .16s
}
html[data-theme="dark"] .toast{background:var(--gray-100);color:var(--gray-900)}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ---------- hero ---------- */
.hero{padding:26px 0 6px}
.hero h1{font-size:clamp(1.6rem,4vw,2.15rem);margin-bottom:.35em}
.hero p{color:var(--text-soft);max-width:60ch;font-size:1.02rem}
.hero-search{max-width:520px;margin-top:16px;position:relative}
.hero-search input[type="search"]{height:44px;font-size:1rem;padding-left:36px}
.hero-search .s-icon{top:14px;left:12px;width:18px;height:18px}
/* The /search/ page: the same box, full width, with the results as a list
   below rather than a popover. */
.search-page{max-width:none;margin:0;flex:1}
.search-page .search-results{display:none!important}
.search-form{display:flex;gap:8px;align-items:stretch}
.search-form .btn{flex:none}

/* ---------- homepage: split hero ----------
   Copy on the left, the live local-time panel on the right. The panel is the
   one thing a visitor most often came for, so it sits above the fold beside the
   pitch rather than below it. */
.hero-split{
  position:relative;
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(300px,.85fr);
  gap:32px;align-items:start;padding:28px 0 8px
}
.hero-copy h1{font-size:clamp(1.9rem,4.2vw,2.75rem);line-height:1.15;margin:.2em 0 .4em}
.h1-accent{color:var(--accent)}

/* A dot field behind the hero, the same faint texture the reference carries.
   Two radial gradients rather than an image: no request, no raster to scale,
   and it recolours with the theme. Masked so it fades out before the copy. */
.hero-split::before{
  content:"";position:absolute;inset:-10px -16px auto -16px;height:280px;
  background-image:radial-gradient(currentColor 1px, transparent 1px);
  background-size:22px 22px;color:var(--accent);opacity:.07;
  -webkit-mask-image:linear-gradient(160deg,#000 0%,transparent 62%);
  mask-image:linear-gradient(160deg,#000 0%,transparent 62%);
  pointer-events:none;z-index:0
}

/* Anchored to the copy column, top-right — the gap the headline and lede leave
   once they wrap. Sits under the text, which stays fully legible over it. */
.hero-art{
  position:absolute;inset-inline-end:-8px;top:-4px;width:min(250px,42%);height:auto;
  pointer-events:none;opacity:.95;z-index:0
}
.hero-copy{position:relative}
.hero-copy > :not(.hero-art){position:relative;z-index:1}
.localtime-card{position:relative;z-index:1}
.hero-badge{
  display:inline-block;font-size:.75rem;font-weight:600;letter-spacing:.03em;
  color:var(--accent-strong);background:var(--accent-soft);
  border:1px solid var(--border);border-radius:99px;padding:3px 10px;margin:0
}
/* Capped so the last line stops short of the artwork rather than running
   under it — the headline already clears it, the lede did not. */
.hero-lede{color:var(--text-soft);max-width:44ch;font-size:1.05rem;margin-bottom:18px}
.hero-find{max-width:560px}
.hero-popular{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:14px 0 0}
.hero-popular .lbl{margin-inline-end:2px}

.localtime-card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:18px
}
.lt-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:6px}
/* A dot that says the clock is running, not a decorative flourish. */
.lt-live{display:inline-flex;align-items:center;gap:6px;font-size:.75rem;font-weight:600;color:var(--success)}
.lt-live::before{content:"";width:7px;height:7px;border-radius:99px;background:var(--success)}
.localtime-card .clock-time{font-size:clamp(2.1rem,5vw,2.9rem);color:var(--accent-strong);margin:0}
.localtime-card .clock-meta{color:var(--text-soft);margin:4px 0 0;font-size:.95rem}
.lt-tiles{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:14px 0 12px}
.lt-tiles > div{background:var(--surface-alt);border:1px solid var(--border);border-radius:var(--radius);padding:8px 10px;min-width:0}
.lt-tiles .k{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-mute);font-weight:600}
.lt-tiles .v{font-family:var(--font-mono);font-size:.85rem;color:var(--text);overflow-wrap:anywhere}
.lt-foot{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:12px}
.lt-note{margin:12px 0 0;font-size:.75rem}

/* ---------- homepage: quick access strip ---------- */
.quick-strip{
  display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:6px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:14px 10px;margin-top:20px
}
.quick-item{
  display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;
  padding:8px 4px;border-radius:var(--radius);color:var(--text-soft);font-size:.78rem;line-height:1.25;
  transition:background-color .12s ease,color .12s ease
}
.quick-item:hover{background:var(--surface-alt);color:var(--text);text-decoration:none}
.quick-ic{
  display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;
  border-radius:99px;background:var(--accent-soft);font-size:1.15rem;line-height:1
}
/* A tint per tool, so the strip reads as a set of distinct destinations rather
   than one repeated button. Kept to soft washes — the icons carry the colour,
   the labels stay neutral. */
.quick-ic[data-tone="0"]{background:var(--surface-alt)}
.quick-ic[data-tone="1"]{background:var(--accent-soft)}
.quick-ic[data-tone="2"]{background:var(--success-soft)}
.quick-ic[data-tone="3"]{background:#f3e8ff}
.quick-ic[data-tone="4"]{background:var(--warning-soft)}
.quick-ic[data-tone="5"]{background:var(--danger-soft)}
.quick-ic[data-tone="6"]{background:#e0f2f1}
html[data-theme="dark"] .quick-ic[data-tone="3"]{background:#2a1f3d}
html[data-theme="dark"] .quick-ic[data-tone="6"]{background:#0f2b2a}

/* ---------- compact world-clock rows (homepage preview) ---------- */
.wc-row{display:flex;align-items:center;gap:10px}
.wc-flag{font-size:1.25rem;line-height:1;flex:none}
.wc-row-main{min-width:0;flex:1}
.wc-row-main .wc-city{font-size:.92rem}
.wc-row-main .wc-country{font-size:.75rem}
.wc-row-time{text-align:end;flex:none}
.wc-row-time .wc-time{font-size:1rem;margin:0}
.wc-row-time .wc-date{font-size:.72rem;color:var(--text-mute)}
[dir="rtl"] .wc-row-time{text-align:start}

/* ---------- homepage: section heads and rows ---------- */
.section-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px}
.section-head h2{margin:0}
.more-link{display:inline-block;font-size:.85rem;font-weight:600;color:var(--accent-strong)}
.card .more-link{margin-top:10px}

.home-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--gap);margin-top:32px;align-items:start}
.home-row .card{height:100%}
.home-row h2{font-size:1.125rem}
.wc-compact{grid-template-columns:1fr;gap:6px}
.wc-compact .wc-item{padding:9px 10px}
.wc-compact .wc-time{font-size:1.1rem;margin:2px 0 0}
.wc-compact .wc-date,.wc-compact .wc-off{font-size:.75rem}

.link-rows{list-style:none;padding:0;margin:0;display:grid;gap:2px}
.link-rows a{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 10px;border-radius:var(--radius);color:var(--text)
}
.link-rows a:hover{background:var(--surface-alt);text-decoration:none}
.link-rows strong{display:block;font-size:.92rem;font-weight:600}
.link-rows em{display:block;font-style:normal;font-size:.8rem;color:var(--text-mute);margin-top:1px}

/* Tool cards gain a trailing arrow, so the whole card reads as a destination. */
.tool-card{position:relative}
.tool-card .go{
  position:absolute;inset-inline-end:12px;bottom:10px;color:var(--text-mute);
  font-size:.95rem;transition:color .12s ease
}
.tool-card:hover .go{color:var(--accent-strong)}
.tool-card .d{padding-inline-end:22px}

/* ---------- homepage: promo bar and feature strip ---------- */
.promo{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:14px;
  background:var(--accent-soft);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:16px 18px;margin-top:32px
}
.promo-title{font-weight:650;margin:0;color:var(--text)}
.promo-sub{margin:2px 0 0;color:var(--text-soft);font-size:.9rem}

.feature-strip{
  list-style:none;padding:0;margin:0;display:grid;gap:10px;
  grid-template-columns:repeat(6,minmax(0,1fr))
}
.feature-strip li{
  display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin:0;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:14px 8px
}
.feature-strip strong{font-size:.85rem;font-weight:600}
.feature-strip span:last-child{font-size:.75rem;color:var(--text-mute);line-height:1.3}
.feature-ic{
  display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;
  border-radius:99px;background:var(--accent-soft);color:var(--accent-strong);font-size:1rem;margin-bottom:2px
}

@media (max-width:980px){
  .hero-split{grid-template-columns:1fr;gap:20px}
  /* Once the hero stacks there is no empty right-hand column for the artwork to
     occupy, and it would sit under the headline instead of beside it. */
  .hero-art{display:none}
  .home-row{grid-template-columns:1fr}
  .quick-strip{grid-template-columns:repeat(4,minmax(0,1fr))}
  .feature-strip{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:560px){
  .quick-strip{grid-template-columns:repeat(3,minmax(0,1fr))}
  .feature-strip{grid-template-columns:repeat(2,minmax(0,1fr))}
  .lt-tiles{grid-template-columns:1fr}
  .promo{flex-direction:column;align-items:flex-start}
}
.home-clock{display:flex;flex-wrap:wrap;align-items:center;gap:24px;justify-content:space-between}

body{min-height:100vh;display:flex;flex-direction:column}
main{flex:1}

/* ---------- date picker ----------
   Replaces the browser's own calendar popup so every platform gets the same
   themed control. The native indicator is hidden rather than the input, so the
   field still types and validates normally. */
.dp-field{position:relative;display:block}
.dp-field input[type="date"]{width:100%;padding-inline-end:38px}
.dp-field input[type="date"]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}
.dp-field input[type="date"]::-webkit-inner-spin-button{display:none}
.dp-trigger{
  position:absolute;inset-inline-end:6px;top:50%;transform:translateY(-50%);
  width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;
  border:0;border-radius:var(--radius);background:none;color:var(--text-mute);cursor:pointer;padding:0
}
.dp-trigger:hover{background:var(--surface-alt);color:var(--accent-strong)}
.dp-trigger svg{width:17px;height:17px}
.dp-field input[type="date"]:focus ~ .dp-trigger{color:var(--accent-strong)}

.dp{
  position:absolute;z-index:120;width:296px;padding:12px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);
  animation:dp-in .12s ease-out
}
@keyframes dp-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.dp{animation:none}}

.dp-head{display:flex;align-items:center;gap:2px;margin-bottom:8px}
/* The title is a button: it steps out to the month grid, then the year grid.
   Styled as text so it reads as a heading, with the affordance on hover. */
.dp-title{
  flex:1;text-align:center;font-weight:650;font-size:.95rem;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-family:inherit;color:var(--text);background:none;border:1px solid transparent;
  border-radius:var(--radius);padding:4px 6px;cursor:pointer
}
.dp-title:hover{background:var(--surface-alt);border-color:var(--border)}

/* Month and year grids. Three columns keeps twelve items square-ish at the
   picker's fixed width, and matches the day grid's row rhythm. */
.dp-choose{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;padding:4px 0}
.dp-choose button{
  font:inherit;font-size:.85rem;padding:9px 4px;min-height:38px;cursor:pointer;
  border:1px solid transparent;border-radius:var(--radius);
  background:none;color:var(--text);
  transition:background-color .12s ease,border-color .12s ease
}
.dp-choose button:hover:not(:disabled){background:var(--accent-soft);border-color:var(--accent);color:var(--accent-strong)}
.dp-choose button.is-current{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:650}
html[data-theme="dark"] .dp-choose button.is-current{color:#12141d}
.dp-choose button:disabled{opacity:.35;cursor:not-allowed}
.dp-nav{
  width:28px;height:28px;flex:none;border:1px solid transparent;border-radius:var(--radius);
  background:none;color:var(--text-soft);font:inherit;font-size:.95rem;line-height:1;cursor:pointer;padding:0
}
.dp-nav:hover{background:var(--surface-alt);color:var(--text);border-color:var(--border)}
/* Flex already puts "previous" on the right in RTL; the chevron glyphs are not
   mirrored by the bidi algorithm, so they must be flipped to match. */
[dir="rtl"] .dp-nav{transform:scaleX(-1)}

.dp-grid .cal{font-size:.86rem}
.dp-grid .cal th{padding:4px 0;font-size:.7rem;color:var(--text-mute)}
.dp-grid .cal td button{min-height:32px;border-radius:var(--radius);font-size:.86rem;font-variant-numeric:tabular-nums}
.dp-grid .cal td button:hover:not(:disabled){background:var(--accent-soft);color:var(--accent-strong)}
.dp-grid .cal td button:disabled{opacity:.3;cursor:not-allowed}
.dp-grid .cal .today{border-color:var(--accent);font-weight:700}
.dp-grid .cal .sel{background:var(--accent);color:#fff;font-weight:700}
html[data-theme="dark"] .dp-grid .cal .sel{color:#12141d}
.dp-grid .cal .sel:hover{background:var(--accent-strong);color:#fff}
.dp-grid .wknum{font-size:.66rem;opacity:.7}

.dp-foot{
  display:flex;gap:6px;align-items:center;
  margin-top:10px;padding-top:10px;border-top:1px solid var(--border)
}
.dp-foot .dp-close{margin-inline-start:auto}

/* On a phone the popover becomes a centred sheet: anchoring a 296 px panel to a
   full-width field leaves it half off-screen. */
@media (max-width:560px){
  .dp{
    position:fixed;top:50%!important;left:50%!important;
    transform:translate(-50%,-50%);width:min(340px,calc(100vw - 32px))
  }
  @keyframes dp-in{from{opacity:0;transform:translate(-50%,-46%)}to{opacity:1;transform:translate(-50%,-50%)}}
  .dp-grid .cal td button{min-height:40px;font-size:.95rem}
}

/* ---------- day / night map ---------- */
.dn-wrap{width:100%;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface-alt)}
.dn-svg{display:block;width:100%;height:auto}
.dn-ocean{fill:var(--surface-alt)}
.dn-grid line{stroke:var(--border);stroke-width:.5;opacity:.7}
.dn-equator{stroke:var(--border-strong);stroke-width:.8;stroke-dasharray:4 4}
.dn-night{fill:#0d1117;opacity:.55}
html[data-theme="dark"] .dn-night{fill:#000;opacity:.6}
.dn-sun circle{fill:var(--warning)}
.dn-sun .dn-glow{fill:var(--warning);opacity:.25}
.dn-city circle{stroke:var(--surface);stroke-width:.8}
.dn-city.is-day circle{fill:var(--warning)}
.dn-city.is-night circle{fill:var(--accent);opacity:.85}
/* The chart is geometry, not geography: never mirror it in RTL. */
[dir="rtl"] .dn-wrap{direction:ltr}

/* ---------- right-to-left ----------
   Layout is mostly logical already; these are the places that need a mirror.
   Numbers, clocks and offsets stay left-to-right so "UTC+5:30" and "09:30"
   are never reordered by the bidi algorithm. */
.submenu-right{left:auto;right:0}
[dir="rtl"] .submenu{left:auto;right:0}
[dir="rtl"] .submenu-right{right:auto;left:0}
[dir="rtl"] .search input[type="search"]{padding:0 30px 0 10px}
[dir="rtl"] .search .s-icon{left:auto;right:9px}
[dir="rtl"] .hero-search .s-icon{left:auto;right:12px}
[dir="rtl"] .breadcrumb li::after{margin-left:0;margin-right:6px}
[dir="rtl"] .wc-actions{right:auto;left:8px}
[dir="rtl"] .mp-grid th:first-child,[dir="rtl"] .mp-grid td:first-child{left:auto;right:0;text-align:left}
[dir="rtl"] .link-list,[dir="rtl"] ul,[dir="rtl"] ol{padding-left:0;padding-right:1.25em}
[dir="rtl"] .legend i{margin-right:0;margin-left:5px}
[dir="rtl"] .nav{margin-left:0;margin-right:6px}
[dir="rtl"] .search{margin-left:0;margin-right:auto}
[dir="rtl"] .clock-time,[dir="rtl"] .big-digits,[dir="rtl"] .wc-time,[dir="rtl"] .wc-off,
[dir="rtl"] .clock-zone,[dir="rtl"] .countdown-grid .n,[dir="rtl"] td.num,[dir="rtl"] .result-grid .v{
  direction:ltr;unicode-bidi:isolate
}
[dir="rtl"] .result-grid div,[dir="rtl"] th,[dir="rtl"] td{text-align:right}
[dir="rtl"] td.num{text-align:left}

/* A 210px popover hung off a 34px button runs off a 360px screen, and which
   edge it runs off depends on writing direction. On narrow viewports anchor it
   to the header instead — static .lang-switch hands the containing block to the
   sticky header, so top:100% lands just below however tall the header wrapped
   to. Placed after the RTL block and specific enough (0,3,0) to beat the
   physical left/right overrides above. */
@media (max-width:900px){
  .lang-switch{position:static}
  .lang-switch .submenu.submenu-right{
    inset-inline-start:auto;inset-inline-end:8px;
    min-width:0;width:max-content;max-width:calc(100vw - 16px)
  }
  /* Here for the same reason — after the physical override, so it wins. The
     drawer spans the header's full width from both inset-inline edges, and the
     mirrored margin above, left over from a margin-left the desktop .nav no
     longer has, would otherwise pull its right edge 6px short in Arabic. */
  [dir="rtl"] .nav{margin-inline:0}
}

/* ---------- results ---------- */
.result{
  background:var(--surface);border:1px solid var(--border);
  border-inline-start:3px solid var(--accent);
  border-radius:var(--radius-lg);padding:16px 18px;margin-top:16px
}
.result h2,.result h3{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-mute);margin:0 0 10px;font-weight:600}
.result-main{font-size:1.9rem;font-weight:680;letter-spacing:-.02em;line-height:1.15;margin:0 0 4px}
.result-sub{color:var(--text-soft);margin:0}
.result-grid{display:grid;gap:1px;background:var(--border);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin-top:14px;grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
.result-grid div{background:var(--surface);padding:9px 12px}
.result-grid dt,.result-grid .k{font-size:.75rem;color:var(--text-mute);text-transform:uppercase;letter-spacing:.05em;font-weight:600}
.result-grid dd,.result-grid .v{margin:0;font-weight:600;font-variant-numeric:tabular-nums}
.result-grid .v{font-family:var(--font-mono);font-size:.95rem}
.result .btn-row{margin-top:14px}
.empty{color:var(--text-mute);font-size:.9rem}
.error-msg{background:var(--danger-soft);color:var(--danger);border:1px solid currentColor;border-radius:var(--radius);padding:9px 12px;font-size:.9rem;margin-top:12px}
.error-msg:empty{display:none}

/* ---------- clock ---------- */
.clock-time{font-size:clamp(2.6rem,10vw,4.5rem);font-weight:700;font-family:var(--font-mono);letter-spacing:-.03em;font-variant-numeric:tabular-nums;line-height:1;margin:0;color:var(--clock)}
.clock-time .sec{color:var(--clock-sec);font-size:.55em;font-weight:600}
.clock-meta{color:var(--text-soft);margin:8px 0 0}
.clock-zone{font-family:var(--font-mono);font-size:.85rem;color:var(--text-mute)}
.badge{display:inline-flex;align-items:center;gap:5px;font-size:.75rem;font-weight:600;padding:2px 8px;border-radius:2px;border:1px solid var(--border);color:var(--text-soft);background:var(--surface-alt)}
.badge-day{background:var(--warning-soft);color:var(--warning);border-color:transparent}
.badge-night{background:var(--accent-soft);color:var(--accent-strong);border-color:transparent}
.badge-dst{background:var(--success-soft);color:var(--success);border-color:transparent}

/* ---------- tables ---------- */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;font-size:.92rem}
th,td{text-align:left;padding:8px 12px;border-bottom:1px solid var(--border);white-space:nowrap}
th{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-mute);font-weight:600;background:none;border-bottom-color:var(--border-strong)}
tbody tr:hover{background:var(--surface-alt)}
td.num{font-family:var(--font-mono);font-size:.88rem;font-variant-numeric:tabular-nums}

/* ---------- tool cards ---------- */
.tool-list{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));padding:0;margin:0;list-style:none}
.tool-card{
  display:block;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:12px 14px;color:var(--text);
  transition:background-color .12s ease,border-color .12s ease
}
/* Hover shifts the fill rather than lifting the card: the design system calls
   for interaction to read as a state change, not as depth. */
.tool-card:hover{background:var(--surface-alt);border-color:var(--border-strong);text-decoration:none}
.tool-card .t{font-weight:620;font-size:.95rem;display:flex;align-items:center;gap:8px}
.tool-card .d{color:var(--text-mute);font-size:.85rem;margin:3px 0 0}
.tool-card .ic{font-size:1rem;line-height:1}

/* ---------- world clock cards ---------- */
.wc-list{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));list-style:none;padding:0;margin:0}
.wc-item{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:12px 14px;position:relative
}
.wc-item[draggable=true]{cursor:grab}
.wc-item.dragging{opacity:.45}
/* The clock is the reason the card exists, so it carries the accent and the
   city name steps back to plain text — otherwise two accent-coloured elements
   compete and neither reads as the primary one. */
.wc-city{font-weight:620;display:flex;align-items:center;gap:6px;color:var(--text)}
a.wc-city:hover{color:var(--accent-strong)}
/* Only the world-clock page hangs buttons in the corner; reserving that gutter
   everywhere squeezed the city name on cards that have none. */
.wc-item:has(.wc-actions) .wc-city{padding-inline-end:52px}
.wc-country{color:var(--text-mute);font-size:.8rem}
.wc-time{font-size:1.7rem;font-weight:700;font-family:var(--font-mono);letter-spacing:-.02em;font-variant-numeric:tabular-nums;margin:6px 0 2px;line-height:1.1;color:var(--clock)}
.wc-time .sec{font-size:.6em;color:var(--clock-sec)}
.wc-date{color:var(--text-soft);font-size:.85rem}
.wc-off{font-family:var(--font-mono);font-size:.78rem;color:var(--text-mute)}
.wc-actions{position:absolute;top:8px;right:8px;display:flex;gap:2px}
.wc-actions .icon-btn{width:26px;height:26px;border-color:transparent;background:none}
.wc-actions .icon-btn svg{width:14px;height:14px}
.wc-item.is-fav .fav-btn{color:var(--warning)}

/* ---------- calendar ---------- */
.cal{width:100%;table-layout:fixed;font-size:.92rem}
.cal th{text-align:center;background:none;border-bottom:1px solid var(--border);padding:6px 2px}
.cal td{text-align:center;padding:0;border:0;white-space:normal}
.cal td button{
  width:100%;aspect-ratio:1/1;min-height:34px;font:inherit;font-size:.9rem;background:none;border:1px solid transparent;
  border-radius:var(--radius);color:var(--text);cursor:pointer;display:flex;align-items:center;justify-content:center;position:relative
}
.cal td button:hover{background:var(--surface-alt)}
.cal .out{color:var(--text-mute);opacity:.55}
.cal .today{border-color:var(--accent);color:var(--accent-strong);font-weight:700}
.cal .sel{background:var(--accent);color:#fff}
.cal .wknum{font-size:.72rem;color:var(--text-mute);font-variant-numeric:tabular-nums}
.cal .has-ev::after{content:"";position:absolute;bottom:4px;width:4px;height:4px;border-radius:50%;background:var(--accent)}
.cal .hol{color:var(--danger);font-weight:600}
.cal-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;flex-wrap:wrap}
.cal-title{font-size:1.1rem;font-weight:650;margin:0}
.year-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.year-grid .cal{font-size:.78rem}
.year-grid .cal td button{min-height:26px;font-size:.78rem}
.year-grid h3{text-align:center;font-size:.9rem;margin:0 0 4px}

/* ---------- timers ---------- */
.big-digits{font-size:clamp(3rem,15vw,6.5rem);font-weight:700;font-family:var(--font-mono);font-variant-numeric:tabular-nums;letter-spacing:-.03em;line-height:1;margin:0;text-align:center;color:var(--clock)}
.big-digits .ms{font-size:.42em;color:var(--clock-sec)}
.countdown-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;text-align:center;margin:6px 0 0}
.countdown-grid .n{font-size:clamp(2rem,9vw,3.4rem);font-weight:700;font-family:var(--font-mono);font-variant-numeric:tabular-nums;line-height:1.05;color:var(--clock)}
.countdown-grid .l{font-size:.75rem;text-transform:uppercase;letter-spacing:.08em;color:var(--text-mute)}
.preset-row{display:flex;flex-wrap:wrap;gap:6px}
.laps{max-height:280px;overflow:auto}
.fs-mode{position:fixed;inset:0;background:var(--bg);z-index:150;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px}
.progress{height:6px;background:var(--surface-alt);border-radius:99px;overflow:hidden;margin-top:14px}
.progress > i{display:block;height:100%;background:var(--accent);width:0;transition:width .25s linear}

/* ---------- meeting planner ---------- */
.mp-grid{font-size:.85rem;border-collapse:separate;border-spacing:0}
.mp-grid th,.mp-grid td{padding:5px 8px;border-bottom:1px solid var(--border);text-align:center}
.mp-grid th:first-child,.mp-grid td:first-child{text-align:right;color:var(--text-mute);font-variant-numeric:tabular-nums;position:sticky;left:0;background:var(--surface)}
.mp-cell{border-radius:3px;padding:3px 6px;display:block;font-variant-numeric:tabular-nums}
.mp-work{background:var(--success-soft);color:var(--success);font-weight:600}
.mp-fringe{background:var(--warning-soft);color:var(--warning)}
.mp-off{background:var(--surface-alt);color:var(--text-mute)}
.mp-best{outline:2px solid var(--accent);outline-offset:-2px}
.legend{display:flex;gap:14px;flex-wrap:wrap;font-size:.82rem;color:var(--text-soft);margin-top:10px}
.legend i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:5px;vertical-align:-1px}

/* ---------- fullscreen panels ----------
   Six tools can send a panel fullscreen. The browser only stretches the box to
   the screen; without these rules the panel keeps its page-flow layout, so the
   content sits at the top-left of a black backdrop instead of on the display
   the user just asked for. html/body are excluded because a whole-document
   fullscreen must keep its normal document layout. */
:not(html):not(body):fullscreen{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;
  width:100%;height:100%;max-width:none;margin:0;padding:clamp(16px,4vw,56px);
  background:var(--bg);border:0;border-radius:0;box-shadow:none;overflow:auto;text-align:center
}
/* The backdrop is painted behind the element and defaults to black, which
   flashes against a light theme. */
:fullscreen::backdrop{background:var(--bg)}
:not(html):not(body):fullscreen > *{margin:0}

/* Use the room the screen just made available. */
:fullscreen .big-digits{font-size:clamp(4rem,19vw,13rem)}
:fullscreen .clock-time{font-size:clamp(3.5rem,15vw,11rem)}
:fullscreen .countdown-grid{gap:clamp(12px,3vw,40px)}
:fullscreen .countdown-grid .n{font-size:clamp(3rem,11vw,8rem)}
:fullscreen .countdown-grid .l{font-size:clamp(.75rem,1.4vw,1.1rem)}
:fullscreen .wc-list{width:min(1500px,100%);grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
:fullscreen .wc-time{font-size:clamp(1.7rem,3.4vw,2.8rem)}
:fullscreen .hint,:fullscreen .btn-row{justify-content:center}


@media print{
  .site-header,.site-footer,.ad-slot,.upsell,.btn-row,.breadcrumb,.no-print,.faq,.search,.consent{display:none!important}
  body{background:#fff;color:#000;font-size:12pt}
  .card,.result{border:1px solid #999;box-shadow:none;break-inside:avoid}
  a{color:#000;text-decoration:none}
  .year-grid{grid-template-columns:repeat(3,1fr)}
  main{padding:0}
}

/* ---------- tiles ----------
   Every boxed, clickable thing on the site shares one visible treatment and one
   hover. Previously each tile was a 0.8px hairline at 1.23 contrast on a page
   only 1.05 away from its own fill, so nothing read as a box and hover barely
   registered. This trades a little of the reference design's flatness for tiles
   you can actually see — the outline does the work, the shadow only seats it. */
.card,.localtime-card,.quick-strip,.tool-card,.wc-item,.feature-strip li,.promo{
  border-color:var(--border-strong);
  box-shadow:var(--shadow-sm)
}

/* Interactive tiles: accent the edge, warm the fill, lift a hair. */
.tool-card,.quick-item,.feature-strip li,.link-rows a,a.chip,.wc-item{
  transition:background-color .13s ease,border-color .13s ease,box-shadow .13s ease,transform .13s ease
}
.tool-card:hover,
.quick-item:hover,
.link-rows a:hover,
a.chip:hover{
  background:var(--accent-soft);
  border-color:var(--accent);
  box-shadow:var(--shadow);
  text-decoration:none
}
.tool-card:hover,.quick-item:hover{transform:translateY(-2px)}
/* .quick-item has no border of its own until hovered, so give it one to grow
   into — otherwise the row jumps by a pixel as the border appears. */
.quick-item{border:1px solid transparent}
.link-rows a{border:1px solid transparent}
a.chip:hover{color:var(--accent-strong)}

/* Keyboard users get the same signal as the mouse, plus the focus ring. */
.tool-card:focus-visible,.quick-item:focus-visible,.link-rows a:focus-visible,a.chip:focus-visible{
  background:var(--accent-soft);border-color:var(--accent)
}

/* Chips sat on exactly the page colour, so they had no edge at all. */
.chip{background:var(--surface)}

@media (prefers-reduced-motion:reduce){
  .tool-card:hover,.quick-item:hover{transform:none}
}


[dir="rtl"] select{background-position:left 9px center}
html[data-theme="dark"] select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b95a4' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")
}
/* The native pickers still need to be reachable after appearance:none. */
input[type=date]::-webkit-calendar-picker-indicator,
input[type=month]::-webkit-calendar-picker-indicator,
input[type=time]::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.55}
input[type=date]::-webkit-calendar-picker-indicator:hover,
input[type=month]::-webkit-calendar-picker-indicator:hover,
input[type=time]::-webkit-calendar-picker-indicator:hover{opacity:1}
/* A range gets no box, but it still needs the control height of its row or it
   sits shorter than the buttons beside it. */
input[type=range]{
  width:100%;height:38px;min-height:38px;padding:0;margin:0;
  background:none;border:0;cursor:pointer;accent-color:var(--accent)
}
input:hover:not(:disabled),select:hover:not(:disabled){border-color:var(--border-stronger)}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)
}
input:disabled,select:disabled{background:var(--surface-alt);color:var(--text-mute)}

.form-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:start}
/* One field plus its action: the field takes the room, the button stays the
   width of its own label. A class rather than an inline style so the mobile
   rule below can still collapse it — inline styles win over any stylesheet. */
.form-row-action{grid-template-columns:1fr auto}
@supports (grid-template-rows:subgrid){
  /* The subgrid and its parent must agree on row-gap. A subgrid that sets its
     own gutter positions its label/control/hint on a different rhythm from the
     tracks it is sitting in, which shifts the control off the row it shares
     with the buttons beside it. */
  .form-row{grid-template-rows:auto auto auto;column-gap:12px;row-gap:6px}
  .form-row > *{grid-row:span 3}
  /* A definite row, not just a span. Grid places definitely-rowed items before
     auto-placed ones, so pinning only the buttons let them claim column 1 and
     jump ahead of the field they belong beside. Giving fields a definite row
     too puts both in the same placement pass, where DOM order is respected. */
  .form-row > .field{grid-row:1 / span 3;grid-template-rows:subgrid;row-gap:6px}
  /* A bare control or button in the row starts on the control line, so it
     aligns with the inputs beside it rather than with their labels. Stretching
     also equalises height, so a .btn-sm sitting next to a full-size primary
     button no longer reads as a different control. */
  .form-row > .btn,.form-row > .btn-row,.form-row > .seg{grid-row:2;align-self:stretch}
  .form-row > .btn-row > .btn{flex:1}
}

/* Once the row collapses to a single column there is nothing left to align, and
   pinning buttons to row 2 actively hurts: with the fields already occupying
   that cell the grid invents extra columns to place them, which is what pushed
   these forms into horizontal scroll on a phone. Stack plainly instead. */
@media (max-width:560px){
  .form-row,.form-row-action{grid-template-columns:1fr;row-gap:12px}
  .form-row > *,
  .form-row > .btn,.form-row > .btn-row,.form-row > .seg{grid-row:auto;align-self:auto}
  .form-row > .field{grid-template-rows:auto auto auto;row-gap:5px}
}
.hint{font-size:.8rem;color:var(--text-mute)}
fieldset{border:1px solid var(--border);border-radius:var(--radius);padding:12px;margin:0 0 12px}
legend{font-size:.82rem;font-weight:600;color:var(--text-soft);padding:0 6px}
.check{display:flex;align-items:center;gap:7px;font-size:.9rem;color:var(--text-soft)}
.check input{width:16px;height:16px;min-height:0;accent-color:var(--accent)}

/* Secondary buttons are an outline and a label — the flat treatment the design
   system specifies. Interaction is a fill change, never a lift. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;font:inherit;font-size:.92rem;font-weight:550;
  padding:8px 14px;min-height:38px;border-radius:var(--radius);cursor:pointer;
  border:1px solid var(--border-strong);background:var(--surface);color:var(--text-soft);
  transition:background-color .12s ease,border-color .12s ease,color .12s ease
}
.btn:hover{background:var(--surface-alt);border-color:var(--border-stronger);color:var(--text);text-decoration:none}
.btn:active{background:var(--gray-100)}
.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-primary:hover{background:var(--accent-strong);border-color:var(--accent-strong);color:#fff}
html[data-theme="dark"] .btn-primary{color:#12141d}
.btn-sm{padding:5px 10px;min-height:30px;font-size:.83rem}
.btn-ghost{border-color:transparent;background:none;color:var(--text-soft);box-shadow:none}
.btn-ghost:hover{background:var(--surface-alt);border-color:transparent}
.btn svg{width:15px;height:15px}
.btn-row{display:flex;flex-wrap:wrap;gap:8px}

.seg{display:inline-flex;border:1px solid var(--border-strong);border-radius:var(--radius);overflow:hidden}
.seg button{font:inherit;font-size:.85rem;padding:6px 11px;background:var(--surface);border:0;cursor:pointer;color:var(--text-soft);min-height:32px}
.seg button+button{border-left:1px solid var(--border)}
.seg button[aria-pressed="true"]{background:var(--accent-soft);color:var(--accent-strong);font-weight:600}

/* ---------- unix time: quick converter ----------
   A timestamp line and a date line that read as one instrument. Each half of
   the date row is a single outlined box, as a native date control looks, drawn
   by a pseudo-element so the field labels can sit above it. Placed last because
   the generic control rules above match these inputs at equal specificity. */
.ux-ts{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.ux-ts input[type="text"]{flex:1 1 15rem;max-width:24rem;font-family:var(--font-mono);font-size:1rem;font-variant-numeric:tabular-nums}
.ux-ts .btn{flex:none}
.icon-btn.ux-gear{width:38px;height:38px}
.icon-btn.ux-gear svg{width:20px;height:20px}
.icon-btn.ux-gear[aria-expanded="true"]{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-strong)}
.ux-prefs{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:10px;padding:10px 12px;background:var(--surface-alt);border:1px solid var(--border);border-radius:var(--radius)}
.ux-prefs .lbl{align-self:center}
.ux-hint{margin:8px 0 0}

.ux-assume{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;margin:16px 0 8px;color:var(--text-soft)}
.ux-assume select{width:auto;min-height:30px;padding-block:2px;padding-inline:8px 30px;font-weight:600}
/* A floor on the label column keeps the two result lists' values in one line. */
.ux-rows{display:grid;grid-template-columns:minmax(7.5rem,max-content) minmax(0,1fr);gap:2px 18px;align-items:center;margin:0}
.ux-dt ~ .ux-out{margin-top:14px}
.ux-rows > div{display:contents}
.ux-rows dt{font-size:.9rem;font-weight:600;color:var(--text-soft)}
.ux-rows dd{display:flex;flex-wrap:wrap;align-items:center;gap:2px 8px;min-width:0;min-height:32px;margin:0}
/* Dates are sentences, so they keep the text face; bare counts take the mono one. */
/* The cap leaves room for the copy button, so a date that wraps keeps its
   button beside it instead of pushing it onto a line of its own. */
.ux-v{max-width:calc(100% - 36px);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#ux-secs,#ux-millis{font-family:var(--font-mono);font-size:.95rem}
.icon-btn.ux-copy{width:28px;height:28px;border-color:transparent;background:none;color:var(--text-mute)}
.icon-btn.ux-copy:hover{background:var(--surface-alt);color:var(--accent-strong)}
.icon-btn.ux-copy svg{width:15px;height:15px}
.ux-zone:empty{display:none}

/* --ux-h is the height every control on the row shares, the site's usual
   control height, so the labels above them line up too. */
.ux-dt{--ux-h:2.625rem;display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px;margin-top:22px;padding-top:20px;border-top:1px solid var(--border)}
.ux-dt .btn,.ux-zone-pick select{height:var(--ux-h);min-height:var(--ux-h);padding-block:0}
.ux-box{position:relative;display:flex;align-items:flex-end;padding-inline:6px}
.ux-box::before{
  content:"";position:absolute;inset:auto 0 0 0;height:var(--ux-h);pointer-events:none;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius)
}
.ux-box:hover::before{border-color:var(--border-stronger)}
.ux-box:focus-within::before{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)}
.ux-part{position:relative;display:flex;flex-direction:column;align-items:center;gap:5px}
.ux-part label{font-size:.7rem;font-weight:600;line-height:1rem;color:var(--text-soft);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}
.ux-box input[type="text"]{
  width:calc(var(--ux-ch, 2) * 1ch + 14px);height:var(--ux-h);min-height:var(--ux-h);padding:0 4px;
  border:0;border-radius:3px;background:transparent;box-shadow:none;
  font-family:var(--font-mono);font-size:1rem;text-align:center;font-variant-numeric:tabular-nums
}
.ux-box input[type="text"]:focus-visible{border:0;box-shadow:none;background:var(--accent-soft);color:var(--accent-strong)}
.ux-sep{position:relative;display:flex;align-items:center;height:var(--ux-h);color:var(--text-mute);font-family:var(--font-mono)}
.ux-box select{width:auto;height:var(--ux-h);min-height:var(--ux-h);margin-inline-start:4px;border:0;background-color:transparent;box-shadow:none;padding-block:0;padding-inline:6px 26px}
.ux-box select:focus-visible{border:0;box-shadow:none;background-color:var(--accent-soft)}
.ux-zone-pick{align-items:stretch}
.ux-zone-pick label{text-align:start}
.ux-zone-pick select{width:auto;min-width:9.5rem}
/* Both set a display of their own after the bare [hidden] rule, which would
   otherwise lose to them: the settings panel and the AM/PM field toggle. */
.ux-prefs[hidden],.ux-part[hidden]{display:none}
/* Year–month–day and hours–minutes–seconds keep their order in RTL, as ISO does. */
[dir="rtl"] .ux-box,[dir="rtl"] .ux-ts input[type="text"]{direction:ltr}

.code-table tbody th{font-size:.92rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--text)}
.code-table code{font-size:.84rem}

@media (max-width:560px){
  .ux-ts input[type="text"]{flex-basis:100%;max-width:none}
  .ux-ts .btn-primary{flex:1}
  .ux-rows{grid-template-columns:minmax(0,1fr);gap:0}
  .ux-rows dt{margin-top:8px}
  .ux-dt .btn-primary{flex:1 1 100%}
}
