/*
 * Pratimāna Accounts — the one stylesheet every page of this service links.
 *
 * Each page used to carry its own copy of the tokens, the ground, the
 * buttons, the header and the card, and the copies had drifted: four
 * button radii, three button heights, two light-theme --text-dim values,
 * a settings page whose light theme never overrode --blue or --danger. One
 * file, one value each. What only one page draws stays in that page.
 *
 * The neutral system (text, hairlines, elevation) and the dark grounds
 * follow assets/pratimana.css on the four properties, so a visitor crossing
 * from a property to sign in sees the same ink on the same grey; the colour
 * is this property's own family of the Master Website Color Spectrum,
 * Violet & Amethyst (the token block below says which catalog colour each
 * token is). This service does not load the kit itself: it serves its own
 * origin and its pages need a fraction of it.
 */

/* ── Tokens ───────────────────────────────────────────────────────────── */
/* The Violet & Amethyst family of the Master Website Color Spectrum: every
   coloured hex is a catalog colour (the light-theme shades are the catalog
   hue darkened until it reads at 4.5:1 on white and #F7F7F8). The dark
   grounds are not the family's: they are Material Design's dark-theme
   surfaces ("darken with grey"), the same three greys on every property,
   because a saturated hue on a tinted near-black vibrates and on grey sits
   still. --key is the property's identity (selected states, outlines,
   lines); --key-ink the same hue lifted one tone so it reads at 4.5:1 as
   TEXT on all three greys, and is what every link and text button wears;
   --key-2 the family's second colour for chips and gradients; --cta the
   one coloured button a page has (.btn-cta). The semantic tokens (--ok,
   --warn, --danger, --info, --live, --muted) are the same on every
   property. Tints are color-mix() of the token, never a hand-typed rgba,
   so a tint can only ever be its token's hue. */
:root{
  --void:#121212;            /* Material dark surface, 00dp */
  --panel:#1E1E1E;           /* 01dp: 5% white over the ground */
  --panel-raised:#242424;    /* 03dp: 8% white over the ground */
  --hairline:rgba(255,255,255,.14);
  --hairline-soft:rgba(255,255,255,.07);
  --rule-strong:rgba(255,255,255,.38);
  /* The edge of a form control. --hairline is 1.5:1 on the field's own
     fill, under the 3:1 a control's boundary needs (WCAG 1.4.11); this is
     3.0:1 on the card and 3.1:1 on the fill. Dividers keep --hairline. */
  --field-border:rgba(255,255,255,.34);
  --text:#FFFFFF;
  --text-dim:rgba(255,255,255,.72);
  --text-faint:rgba(255,255,255,.58);
  --key:#8B5CF6;             /* Royal Violet: a line or fill, 3.67:1 on --panel-raised; never text on dark */
  --key-ink:#9E76F7;         /* Royal Violet lifted one tone: 5.70:1 on --void, 5.07:1 on --panel, 4.72:1 on --panel-raised */
  --key-2:#B39CFF;           /* Electric Lavender */
  --cta:#8655F6;
  --on-cta:#FFFFFF;          /* 4.52:1 on --cta */
  --info:#3B93F5;
  --info-ink:#7DD3FC;        /* Ice Blue Glaze */
  --ok:#10B981;              /* Phosphor Emerald */
  --warn:#F59E0B;            /* Saffron Amber */
  --danger:#F15A5A;          /* Crimson Flame lifted one tone: 4.69:1 on --panel-raised (the kit's dark value) */
  --danger-fill:#EB0D33;     /* .btn-danger: 4.53:1 under white */
  --live:#00D2FF;            /* Interceptor Cyan */
  --muted:#8E8E93;           /* Titanium Slate */
  /* Selected states (a picked account-type card, the active appearance
     segment, this device's row in the sessions table). The catalog gives
     the light theme Lilac Mist; dark has no surface colour of its own, so
     it is the key at the catalog's 12% tint. */
  --accent-surface:color-mix(in srgb, var(--key) 12%, transparent);
  /* The sign-in card's outline: the catalog's Purple Hairline,
     rgba(139,92,246,.2), which is the key at 20%. */
  --card-line:color-mix(in srgb, var(--key) 20%, transparent);
  --ok-tint:color-mix(in srgb, var(--ok) 12%, transparent);
  --danger-tint:color-mix(in srgb, var(--danger) 12%, transparent);
  --danger-line:color-mix(in srgb, var(--danger) 42%, transparent);
  /* The ring a picked card wears, and the one every control wears when
     focused from the keyboard: ink over the ground, never a colour. */
  --key-glow:color-mix(in srgb, var(--key) 18%, transparent);
  --ring:0 0 0 2px var(--void), 0 0 0 4px var(--text);
  /* The avatar's initials sit on a gradient of the family's hue. White on
     Royal Violet is 4.22:1 and on Electric Lavender 2.30:1, both under
     the 4.5:1 the initials need, so the gradient runs from the family's
     CTA shade (#8655F6, 4.52:1 under white) to the light-theme key
     (#6A2EF3, 6.37:1) instead: the same hue, one step deeper at each end. */
  --avatar-from:#8655F6;
  --avatar-to:#6A2EF3;
  --grad-avatar:linear-gradient(135deg, var(--avatar-from), var(--avatar-to));
  --grad-btn:linear-gradient(90deg, var(--key-2), var(--key));
  --header-bg:color-mix(in srgb, var(--void) 62%, transparent);
  --shadow-soft:rgba(0,0,0,.35);
  --glow:0 0 0 1px rgba(255,255,255,.10), 0 10px 40px rgba(255,255,255,.07);
  --scrim:rgba(0,0,0,.6);
  /* The kit's elevation and two of its spectrum stops, which the account
     chip (assets/auth.js, a kit file) draws with: the chip's shadow and
     its avatar's gradient, which is this page's avatar gradient. The kit
     also reads --blue (its focus ring, and the language menu's current
     entry, which is text): the key-ink here, so it reads on the grey. */
  --shadow-sm:0 1px 2px rgba(0,0,0,.5), 0 4px 12px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.045);
  --shadow-lg:0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45), 0 32px 72px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.07);
  --g6:var(--avatar-from);
  --g8:var(--avatar-to);
  --blue:var(--key-ink);
  --blue-glow:var(--key-glow);
  /* One height for every control in a masthead or a settings card, and
     the 44px a touch target wants. Full-width form buttons are taller
     (.btn-block). */
  --control-h:44px;
  --font-display:-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";
  --font-mono:ui-monospace, SFMono-Regular, "SF Mono", Menlo, "Cascadia Mono", Consolas, "Roboto Mono", "Liberation Mono", monospace;
}
[data-theme="light"]{
  --void:#FFFFFF;
  --panel:#F7F7F8;
  --panel-raised:#F7F7F8;
  --hairline:rgba(0,0,0,.12);
  --hairline-soft:rgba(0,0,0,.06);
  --rule-strong:rgba(0,0,0,.46);
  /* 3.5:1 on white, 3.4:1 on the field's fill. */
  --field-border:rgba(0,0,0,.46);
  --text:#000000;
  --text-dim:rgba(0,0,0,.64);
  --text-faint:rgba(0,0,0,.58);
  /* Royal Violet is 3.07:1 on white: too faint for a link. Darkened to
     #6A2EF3 it is 6.37:1 on white and 5.95:1 on the panel. */
  --key:#6A2EF3;
  --key-ink:#6A2EF3;
  --key-2:#5F2EFF;
  --cta:#8655F6;
  --on-cta:#FFFFFF;
  --info:#006EDE;
  --info-ink:#036695;
  --ok:#047857;
  --warn:#92400E;
  --danger:#DC2626;          /* 4.83:1 on white, 4.51:1 on the panel */
  --danger-fill:#DC2626;
  --live:#007C96;
  --muted:#717176;
  --accent-surface:#DDD6FE;  /* Lilac Mist */
  --card-line:var(--hairline);
  --ok-tint:color-mix(in srgb, var(--ok) 8%, transparent);
  --danger-tint:color-mix(in srgb, var(--danger) 8%, transparent);
  --danger-line:color-mix(in srgb, var(--danger) 42%, transparent);
  --header-bg:color-mix(in srgb, var(--void) 72%, transparent);
  --shadow-soft:rgba(20,24,35,.08);
  --glow:0 0 0 1px rgba(0,0,0,.08), 0 10px 34px rgba(20,20,30,.12);
  --scrim:rgba(0,0,0,.28);
  --shadow-sm:0 1px 2px rgba(0,0,0,.02), 0 4px 10px rgba(0,0,0,.03);
  --shadow-lg:0 2px 4px rgba(0,0,0,.02), 0 12px 28px rgba(0,0,0,.04), 0 24px 60px rgba(0,0,0,.05);
  /* The frosted treatment the properties' light theme gives a ghost
     control, and the ink a primary button is filled with. */
  --glass:rgba(255,255,255,.5);
  --glass-hover:rgba(255,255,255,.68);
  --glass-edge:rgba(255,255,255,.6);
  --glass-shadow:rgba(20,24,35,.07);
  --ink-fill:rgba(18,21,29,.82);
  --ink-fill-line:rgba(18,21,29,.85);
  --ink-fill-hover:rgba(18,21,29,.92);
}

/* ── Base ─────────────────────────────────────────────────────────────── */
*{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0; background:var(--void); color:var(--text);
  font-family:var(--font-display); -webkit-font-smoothing:antialiased;
  line-height:1.5; min-height:100vh; display:flex; flex-direction:column;
  transition:background-color .3s ease, color .3s ease;
}
a{ color:inherit; text-decoration:none; }
img,svg{ display:block; max-width:100%; }
/* The UA's [hidden]{display:none} loses to any author rule that sets
   display, which is most of the components below. */
[hidden]{ display:none !important; }
.wrap{ max-width:1180px; margin:0 auto; padding:0 32px; width:100%; }

/* Off the page but not out of the accessibility tree. */
.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0;
}

/* The first thing a keyboard reaches on every page: past the masthead
   (or the settings bar) to the page's own content. Out of sight until
   focused. */
.skip-link{
  position:absolute; top:8px; left:8px; z-index:200;
  padding:10px 16px; border-radius:10px; min-height:var(--control-h);
  display:inline-flex; align-items:center;
  background:var(--text); color:var(--void); font-size:14px; font-weight:600;
  transform:translateY(-200%); transition:transform .15s ease;
}
.skip-link:focus{ transform:none; outline:none; box-shadow:var(--ring); }
[dir="rtl"] .skip-link{ left:auto; right:8px; }
main:focus{ outline:none; }

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:var(--control-h); padding:0 18px; border-radius:10px;
  border:1px solid transparent; background:transparent; color:var(--text);
  font-family:inherit; font-size:14px; font-weight:600; line-height:1.25;
  cursor:pointer; text-decoration:none; transition:all .18s ease;
}
.btn-block{ width:100%; min-height:48px; }
.btn-primary{ background:var(--text); color:var(--void); }
.btn-primary:hover:not(:disabled){ filter:brightness(1.08); transform:translateY(-1px); }
.btn-ghost{ border-color:var(--hairline); color:var(--text); background:transparent; }
.btn-ghost:hover:not(:disabled){ border-color:var(--text-dim); }
/* The one coloured button a page has: the sign-in's "Continue with email"
   and the code step's "Verify". Every other primary is .btn-primary, ink. */
.btn-cta{ background:var(--cta); color:var(--on-cta); border-color:var(--cta); }
.btn-cta:hover:not(:disabled){ filter:brightness(1.08); transform:translateY(-1px); }
/* Delete account: a filled destructive button, white on the danger fill. */
.btn-danger{ background:var(--danger-fill); color:var(--on-cta); border-color:var(--danger-fill); }
.btn-danger:hover:not(:disabled){ filter:brightness(1.08); transform:translateY(-1px); }
/* A busy button is disabled too, and keeps full strength: the spinner on
   it is the message. */
.btn:disabled:not([aria-busy="true"]){ opacity:.5; cursor:not-allowed; }
.btn:focus-visible{ outline:none; box-shadow:var(--ring); }

/* Light theme: the frosted treatment the properties use, the primary in
   ink. The glass alone has no edge on a white ground, so the ghost
   controls keep their hairline (the override used to replace it with a
   white border, which on white is no border at all). */
[data-theme="light"] .btn-ghost,
[data-theme="light"] .theme-toggle{
  background:var(--glass);
  backdrop-filter:blur(18px) saturate(180%);
  -webkit-backdrop-filter:blur(18px) saturate(180%);
  border-color:var(--hairline);
  box-shadow:0 4px 18px var(--glass-shadow), inset 0 1px 0 var(--glass-edge);
}
[data-theme="light"] .btn-ghost:hover:not(:disabled),
[data-theme="light"] .theme-toggle:hover{ background:var(--glass-hover); border-color:var(--text-dim); }
[data-theme="light"] .btn-primary{ background:var(--ink-fill); color:var(--void); border-color:var(--ink-fill-line); }
[data-theme="light"] .btn-primary:hover:not(:disabled){ background:var(--ink-fill-hover); }
/* A focused ghost or primary keeps its own shadow under the ring. */
[data-theme="light"] .btn:focus-visible,
[data-theme="light"] .theme-toggle:focus-visible{ box-shadow:var(--ring); }

/* The theme toggle, and the language switcher assets/i18n.js puts beside it. */
.theme-toggle{
  width:var(--control-h); height:var(--control-h); border-radius:10px; border:1px solid var(--hairline);
  background:transparent; display:inline-flex; align-items:center; justify-content:center;
  cursor:pointer; transition:border-color .2s ease, transform .2s ease, background-color .2s ease;
  color:var(--text); flex-shrink:0; padding:0;
}
.theme-toggle:hover{ border-color:var(--text-dim); transform:translateY(-1px); background:var(--panel); }
.theme-toggle:active{ transform:translateY(0) scale(.94); }
.theme-toggle:focus-visible{ outline:none; box-shadow:var(--ring); }
.theme-toggle svg{ width:17px; height:17px; }
.theme-toggle .icon-moon{ display:none; }
.theme-toggle[data-current="light"] .icon-sun{ display:none; }
.theme-toggle[data-current="light"] .icon-moon{ display:block; }

/* ── Header ───────────────────────────────────────────────────────────── */
.site-header{
  position:sticky; top:0; z-index:50;
  backdrop-filter:blur(22px) saturate(180%);
  -webkit-backdrop-filter:blur(22px) saturate(180%);
  background:var(--header-bg); border-bottom:1px solid var(--hairline-soft);
  box-shadow:0 1px 0 var(--hairline-soft) inset, 0 12px 30px -18px var(--shadow-soft);
}
.site-header nav{ display:flex; align-items:center; justify-content:flex-start; gap:48px; height:76px; }
/* flex-shrink:0 mirrors assets/pratimana.css: without it the nav squeezed
   the wordmark as the viewport narrowed, to nothing at 320px. */
.logo-link{ display:inline-flex; flex-shrink:0; margin-inline-start:8px; border-radius:6px; }
.logo-link:focus-visible{ outline:none; box-shadow:var(--ring); }
.logo-mark{ height:26px; flex-shrink:0; color:var(--text); }
.logo-mark text{ fill:currentColor; }
/* The wordmark is SVG <text>; under dir="rtl" it inherits right-to-left
   direction, anchors at its right end and draws off the canvas. */
.logo-mark text{ direction:ltr; unicode-bidi:bidi-override; }
.nav-actions{ display:flex; align-items:center; gap:14px; margin-inline-start:auto; }
.site-header .btn,
.site-header .theme-toggle,
.site-header .lang-toggle{
  height:var(--control-h); min-height:0; padding-top:0; padding-bottom:0;
  display:inline-flex; align-items:center; justify-content:center;
}
.site-header .lang-toggle{ min-width:var(--control-h); border-radius:10px; }
.site-header .theme-toggle{ width:var(--control-h); }

/* ── Footer ───────────────────────────────────────────────────────────── */
.site-footer{ border-top:1px solid var(--hairline-soft); padding:26px 0; }
.footer-row{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:12px; }
.footer-row .fbrand{ font-size:13px; color:var(--text-faint); }
/* Wraps because it must: at 320px the four links measure 328px against a
   256px content box. Padding grows each link to a 27px target (WCAG 2.5.8
   asks 24) and the negative margin leaves the row where it was. */
.footer-row .flinks{ display:flex; flex-wrap:wrap; gap:6px 22px; font-size:13px; color:var(--text-dim); }
.footer-row .flinks a{ padding:4px 0; margin:-4px 0; transition:color .18s ease; }
.footer-row .flinks a:hover{ color:var(--text); }
.footer-row .flinks a:focus-visible{ outline:none; box-shadow:var(--ring); border-radius:4px; }

/* Breakpoints and values mirror assets/pratimana.css, so the headers
   narrow the same way. */
@media (max-width:620px){
  .wrap{ padding:0 20px; }
  .logo-mark{ height:22px; }
  .site-header nav{ gap:20px; }
}
@media (max-width:420px){
  .nav-actions{ gap:6px; }
  /* "Back to site" on one line: it broke over two at 360 and three at 320. */
  .nav-actions .btn{ padding-left:12px; padding-right:12px; font-size:13px; white-space:nowrap; }
  /* The globe alone carries the language control; its aria-label is unchanged. */
  .lang-toggle-label{ display:none; }
}
@media (max-width:360px){
  .wrap{ padding:0 14px; }
  .site-header nav{ gap:12px; }
}

/* ── The sign-in pages' ground and card ───────────────────────────────── */
/* A plain ground in both themes. The card hangs from a fixed top rather
   than sitting centred, so what comes and goes inside it grows it
   downwards and never slides it under the pointer. */
.auth-main{ flex:1; display:flex; align-items:flex-start; justify-content:center; padding:clamp(40px, 12vh, 112px) 24px 56px; position:relative; }
.auth-card{
  position:relative; z-index:1; width:100%; max-width:400px;
  background:var(--panel); border:1px solid var(--card-line); border-radius:8px; padding:38px 34px;
  animation:fadeUp .6s cubic-bezier(.16,1,.3,1) both;
}
.auth-card h1{ font-size:26px; font-weight:800; letter-spacing:-0.02em; line-height:1.25; margin:0 0 10px; text-wrap:balance; }
@media (max-width:480px){ .auth-card{ padding:30px 22px; } }
/* Korean breaks between any two syllables by default. */
:lang(ko) h1, :lang(ko) h2{ word-break:keep-all; }

.spinner{ width:34px; height:34px; border-radius:50%; border:3px solid var(--hairline); border-top-color:var(--text); margin:0 auto 20px; animation:spin .8s linear infinite; }
.check, .cross{ width:52px; height:52px; border-radius:50%; display:flex; align-items:center; justify-content:center; margin:0 auto 18px; }
.check{ background:var(--ok-tint); color:var(--ok); animation:pop .4s cubic-bezier(.34,1.56,.64,1); }
.cross{ background:var(--danger-tint); color:var(--danger); }

@keyframes spin{ to{ transform:rotate(360deg); } }
@keyframes fadeUp{ from{ opacity:0; transform:translateY(14px); } to{ opacity:1; transform:translateY(0); } }
@keyframes pop{ from{ transform:scale(.4); opacity:0; } to{ transform:scale(1); opacity:1; } }

/* ── Reduced motion ───────────────────────────────────────────────────── */
/* Every entrance, shake, pop and slide stops, and so does smooth
   scrolling. Spinners keep turning, slowly: a ring that does not move
   next to no words reads as a broken button. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *:not(.spinner):not(.otp-spinner), *::before, *::after{ animation:none !important; }
  *, *::before, *::after{ transition:none !important; }
  .spinner, .otp-spinner{ animation-duration:2.4s !important; }
}
