/* =====================================================================
   PURESOFT UI
   The shared design system. Tokens and components live here; the admin
   and public stylesheets hold layout only and consume these tokens.

   Load order matters:  fonts.css -> ui.css -> admin.css | app.css
   ===================================================================== */

:root{
  /* ------------------------------------------------------- typeface */
  --font-display:'Comfortaa', ui-rounded, 'Segoe UI', system-ui, sans-serif;
  --font-body:'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono:'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  /* Legacy alias. The old stylesheets used --font-head for buttons, labels
     and navigation as well as headings, and those must stay on the body
     face, so the alias resolves to it. Headings opt into the display face
     explicitly. */
  --font-head:var(--font-body);

  /* ---------------------------------------------------- type scale */
  --text-2xs:.6875rem;   /* 11px  meta, counters            */
  --text-xs:.75rem;      /* 12px  captions, table headers   */
  --text-sm:.8125rem;    /* 13px  helper text               */
  --text-base:.875rem;   /* 14px  body                      */
  --text-md:.9375rem;    /* 15px  emphasised body           */
  --text-lg:1.0625rem;   /* 17px  card titles               */
  --text-xl:1.25rem;     /* 20px  section titles            */
  --text-2xl:1.5rem;     /* 24px  page titles               */
  --text-3xl:1.875rem;   /* 30px  hero titles               */

  --leading-tight:1.25;
  --leading-snug:1.4;
  --leading-normal:1.6;
  --leading-relaxed:1.75;

  --fw-regular:400;
  --fw-medium:500;
  --fw-semibold:600;
  --fw-bold:700;

  /* Comfortaa sits optically small and wide; these two keep display
     type balanced against DM Sans without per-heading fiddling. */
  --display-tracking:-.005em;
  --body-tracking:0;

  /* -------------------------------------------------- spacing scale */
  --space-0:0;
  --space-1:.25rem;
  --space-2:.5rem;
  --space-3:.75rem;
  --space-4:1rem;
  --space-5:1.25rem;
  --space-6:1.5rem;
  --space-8:2rem;
  --space-10:2.5rem;
  --space-12:3rem;
  --space-16:4rem;

  /* --------------------------------------------------------- radius */
  --radius-xs:6px;
  --radius-sm:8px;
  --radius-md:12px;
  --radius-lg:16px;
  --radius-xl:22px;
  --radius-full:999px;

  /* ------------------------------------------------------ elevation */
  --elev-1:0 1px 2px rgba(10,19,48,.06), 0 1px 3px rgba(10,19,48,.05);
  --elev-2:0 2px 6px rgba(10,19,48,.06), 0 4px 14px rgba(10,19,48,.06);
  --elev-3:0 8px 20px rgba(10,19,48,.09), 0 2px 6px rgba(10,19,48,.05);
  --elev-4:0 20px 48px rgba(10,19,48,.16), 0 6px 16px rgba(10,19,48,.08);

  /* ----------------------------------------------------- icon sizes */
  --icon-xs:14px;
  --icon-sm:16px;
  --icon-md:20px;
  --icon-lg:24px;
  --icon-xl:32px;

  /* --------------------------------------------------------- motion */
  --ease-out:cubic-bezier(.22,1,.36,1);
  --ease-in-out:cubic-bezier(.65,0,.35,1);
  --ease-spring:cubic-bezier(.34,1.4,.64,1);
  --dur-fast:120ms;
  --dur-base:200ms;
  --dur-slow:320ms;

  /* ---------------------------------------------------- brand scale */
  --navy:#0a1330;
  --navy-2:#111e4a;
  --navy-3:#18255c;
  --navy-4:#24356f;
  --red:#e31e2b;
  --red-dark:#bf1622;
  --red-darker:#9c111c;
  --red-soft:rgba(227,30,43,.10);
  --red-softer:rgba(227,30,43,.05);

  /* -------------------------------------------------- neutral scale */
  --n-0:#ffffff;
  --n-25:#fbfcfe;
  --n-50:#f6f8fc;
  --n-100:#eef1f7;
  --n-200:#e1e6ef;
  --n-300:#c9d1e0;
  --n-400:#9aa5bb;
  --n-500:#6b7691;
  --n-600:#4d5875;
  --n-700:#343e58;
  --n-800:#20293f;
  --n-900:#0f1628;

  --ink:#1f2937;
  --muted:var(--n-500);
  --line:var(--n-200);
  --line-2:var(--n-100);

  /* ------------------------------------------------ semantic colour */
  --success:#15803d;
  --success-strong:#166534;
  --success-bg:#f0fdf4;
  --success-border:#bbf7d0;

  --warning:#b45309;
  --warning-strong:#92400e;
  --warning-bg:#fffbeb;
  --warning-border:#fde68a;

  --danger:#dc2626;
  --danger-strong:#b91c1c;
  --danger-bg:#fef2f2;
  --danger-border:#fecaca;

  --info:#1d4ed8;
  --info-strong:#1e40af;
  --info-bg:#eff6ff;
  --info-border:#bfdbfe;

  /* Legacy aliases kept so existing rules resolve. */
  --green:var(--success);
  --amber:var(--warning);
  --blue:var(--info);

  /* ----------------------------------------------------- focus ring */
  --ring-width:3px;
  --ring-color:rgba(227,30,43,.28);
  --ring-color-info:rgba(29,78,216,.25);
}

@media (prefers-reduced-motion: reduce){
  :root{--dur-fast:0ms;--dur-base:0ms;--dur-slow:0ms}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* =====================================================================
   TYPOGRAPHY
   Comfortaa carries identity, DM Sans carries the work, JetBrains Mono
   carries anything the user has to read character by character.
   ===================================================================== */

.u-display{font-family:var(--font-display);font-weight:var(--fw-semibold);letter-spacing:var(--display-tracking)}
.u-body{font-family:var(--font-body)}
.u-mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}

.u-title-lg{font-family:var(--font-display);font-size:var(--text-2xl);font-weight:var(--fw-bold);line-height:var(--leading-tight);letter-spacing:var(--display-tracking);color:var(--navy)}
.u-title{font-family:var(--font-display);font-size:var(--text-xl);font-weight:var(--fw-semibold);line-height:var(--leading-tight);letter-spacing:var(--display-tracking);color:var(--navy)}
.u-title-sm{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--fw-semibold);line-height:var(--leading-snug);color:var(--navy)}
.u-lede{font-family:var(--font-body);font-size:var(--text-md);line-height:var(--leading-normal);color:var(--muted)}
.u-help{font-family:var(--font-body);font-size:var(--text-sm);line-height:var(--leading-snug);color:var(--muted)}
.u-meta{font-family:var(--font-body);font-size:var(--text-xs);color:var(--muted)}

/* =====================================================================
   ICONS
   One scale, optically aligned to the text beside it.
   ===================================================================== */

.ico{display:inline-flex;align-items:center;justify-content:center;flex:none;line-height:1}
.ico-xs{font-size:var(--icon-xs);width:var(--icon-xs);height:var(--icon-xs)}
.ico-sm{font-size:var(--icon-sm);width:var(--icon-sm);height:var(--icon-sm)}
.ico-md{font-size:var(--icon-md);width:var(--icon-md);height:var(--icon-md)}
.ico-lg{font-size:var(--icon-lg);width:var(--icon-lg);height:var(--icon-lg)}
.ico-xl{font-size:var(--icon-xl);width:var(--icon-xl);height:var(--icon-xl)}

/* A tinted square behind an icon, used in dialog headers and cards. */
.ico-badge{
  display:grid;place-items:center;flex:none;
  width:44px;height:44px;border-radius:var(--radius-md);
  background:var(--n-100);color:var(--n-600);font-size:var(--icon-md);
}
.ico-badge.is-danger{background:var(--danger-bg);color:var(--danger)}
.ico-badge.is-warning{background:var(--warning-bg);color:var(--warning)}
.ico-badge.is-success{background:var(--success-bg);color:var(--success)}
.ico-badge.is-info{background:var(--info-bg);color:var(--info)}
.ico-badge.is-brand{background:var(--red-soft);color:var(--red)}

/* =====================================================================
   BUTTONS
   Four intents, so emphasis carries meaning rather than decoration:
     primary     go ahead, the expected action
     destructive irreversible, removes or revokes something
     warning     disruptive but recoverable
     neutral     step back, cancel, keep things as they are
   ===================================================================== */

.ui-btn{
  --btn-bg:var(--n-0);
  --btn-fg:var(--navy);
  --btn-border:var(--line);
  --btn-bg-hover:var(--n-50);
  --btn-shadow-hover:var(--elev-2);

  display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  font-family:var(--font-body);font-size:var(--text-base);font-weight:var(--fw-semibold);
  line-height:1.2;letter-spacing:var(--body-tracking);
  padding:.625rem 1.125rem;min-height:40px;
  border:1px solid var(--btn-border);border-radius:var(--radius-sm);
  background:var(--btn-bg);color:var(--btn-fg);
  cursor:pointer;white-space:nowrap;text-decoration:none;
  transition:background var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-base) var(--ease-out),
             transform var(--dur-fast) var(--ease-out);
  position:relative;isolation:isolate;
}
.ui-btn > i,.ui-btn > .ico{font-size:var(--icon-sm);flex:none}
.ui-btn:hover:not(:disabled):not([aria-busy="true"]){background:var(--btn-bg-hover);color:var(--btn-fg);box-shadow:var(--btn-shadow-hover)}
.ui-btn:active:not(:disabled):not([aria-busy="true"]){transform:translateY(1px);box-shadow:none}
.ui-btn:focus-visible{outline:none;box-shadow:0 0 0 var(--ring-width) var(--ring-color)}
.ui-btn:disabled,.ui-btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed;box-shadow:none}

/* ---- intents */
.ui-btn-primary{
  --btn-bg:var(--red);--btn-fg:#fff;--btn-border:var(--red);
  --btn-bg-hover:var(--red-dark);--btn-shadow-hover:0 6px 18px rgba(227,30,43,.30);
}
.ui-btn-primary:hover:not(:disabled){border-color:var(--red-dark)}

.ui-btn-navy{
  --btn-bg:var(--navy);--btn-fg:#fff;--btn-border:var(--navy);
  --btn-bg-hover:var(--navy-2);--btn-shadow-hover:0 6px 18px rgba(10,19,48,.26);
}
.ui-btn-navy:hover:not(:disabled){border-color:var(--navy-2)}

.ui-btn-destructive{
  --btn-bg:var(--danger);--btn-fg:#fff;--btn-border:var(--danger);
  --btn-bg-hover:var(--danger-strong);--btn-shadow-hover:0 6px 18px rgba(220,38,38,.30);
}
.ui-btn-destructive:hover:not(:disabled){border-color:var(--danger-strong)}
.ui-btn-destructive:focus-visible{box-shadow:0 0 0 var(--ring-width) rgba(220,38,38,.30)}

.ui-btn-warning{
  --btn-bg:var(--warning);--btn-fg:#fff;--btn-border:var(--warning);
  --btn-bg-hover:var(--warning-strong);--btn-shadow-hover:0 6px 18px rgba(180,83,9,.28);
}
.ui-btn-warning:hover:not(:disabled){border-color:var(--warning-strong)}

.ui-btn-success{
  --btn-bg:var(--success);--btn-fg:#fff;--btn-border:var(--success);
  --btn-bg-hover:var(--success-strong);--btn-shadow-hover:0 6px 18px rgba(21,128,61,.26);
}

/* Neutral is the default look, named explicitly for intent at call sites. */
.ui-btn-neutral{--btn-bg:var(--n-0);--btn-fg:var(--navy);--btn-border:var(--line);--btn-bg-hover:var(--n-50)}
.ui-btn-neutral:hover:not(:disabled){border-color:var(--n-300)}

.ui-btn-quiet{--btn-bg:transparent;--btn-fg:var(--n-600);--btn-border:transparent;--btn-bg-hover:var(--n-100);--btn-shadow-hover:none}

/* A destructive action that should not shout until it is chosen. */
.ui-btn-destructive-quiet{--btn-bg:var(--n-0);--btn-fg:var(--danger);--btn-border:var(--danger-border);--btn-bg-hover:var(--danger-bg);--btn-shadow-hover:none}

/* ---- sizes */
.ui-btn-sm{font-size:var(--text-sm);padding:.4375rem .875rem;min-height:34px;border-radius:var(--radius-xs)}
.ui-btn-sm > i{font-size:var(--icon-xs)}
.ui-btn-lg{font-size:var(--text-md);padding:.8125rem 1.5rem;min-height:48px;border-radius:var(--radius-md)}
.ui-btn-lg > i{font-size:var(--icon-md)}
.ui-btn-block{width:100%}

/* ---- loading: the label stays for width, a spinner replaces it visually */
.ui-btn[aria-busy="true"]{cursor:progress;color:transparent!important}
.ui-btn[aria-busy="true"] > *{visibility:hidden}
.ui-btn[aria-busy="true"]::after{
  content:'';position:absolute;inset:0;margin:auto;
  width:18px;height:18px;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  color:var(--btn-fg);visibility:visible;
  animation:ui-spin .6s linear infinite;
}
@keyframes ui-spin{to{transform:rotate(360deg)}}

/* =====================================================================
   SPINNER
   ===================================================================== */
.ui-spinner{
  display:inline-block;width:18px;height:18px;border-radius:50%;
  border:2px solid var(--n-300);border-top-color:var(--red);
  animation:ui-spin .6s linear infinite;flex:none;
}
.ui-spinner-sm{width:14px;height:14px;border-width:2px}
.ui-spinner-lg{width:26px;height:26px;border-width:3px}
.ui-spinner-light{border-color:rgba(255,255,255,.35);border-top-color:#fff}

/* =====================================================================
   FIELDS
   ===================================================================== */

.ui-field{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
.ui-label{
  font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--fw-medium);
  color:var(--navy);display:flex;align-items:center;gap:var(--space-2);
}
.ui-label .req{color:var(--danger);font-weight:var(--fw-semibold)}
.ui-label .ui-optional{color:var(--muted);font-weight:var(--fw-regular);font-size:var(--text-xs);margin-left:auto}

.ui-input,.ui-select,.ui-textarea{
  width:100%;font-family:var(--font-body);font-size:var(--text-base);color:var(--ink);
  background:var(--n-0);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:.625rem .8125rem;min-height:42px;outline:none;
  transition:border-color var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out),
             background var(--dur-fast) var(--ease-out);
}
.ui-textarea{min-height:96px;resize:vertical;line-height:var(--leading-normal)}
.ui-select{
  appearance:none;padding-right:2.25rem;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16' fill='none' stroke='%236b7691' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .75rem center;
}
.ui-input::placeholder,.ui-textarea::placeholder{color:var(--n-400)}
.ui-input:hover:not(:disabled),.ui-select:hover:not(:disabled),.ui-textarea:hover:not(:disabled){border-color:var(--n-300)}
.ui-input:focus,.ui-select:focus,.ui-textarea:focus{border-color:var(--red);box-shadow:0 0 0 var(--ring-width) var(--ring-color)}
.ui-input:disabled,.ui-select:disabled,.ui-textarea:disabled{background:var(--n-50);color:var(--n-400);cursor:not-allowed}
.ui-input[readonly]{background:var(--n-50)}

/* ---- validation states */
.ui-field.is-invalid .ui-input,
.ui-field.is-invalid .ui-select,
.ui-field.is-invalid .ui-textarea{border-color:var(--danger);background:var(--danger-bg)}
.ui-field.is-invalid .ui-input:focus,
.ui-field.is-invalid .ui-textarea:focus{box-shadow:0 0 0 var(--ring-width) rgba(220,38,38,.22)}
.ui-field.is-valid .ui-input{border-color:var(--success)}

.ui-hint{font-family:var(--font-body);font-size:var(--text-sm);color:var(--muted);line-height:var(--leading-snug)}

/* Inline validation message. Announced, not merely coloured, and it
   animates in so the change is noticed without being jarring. */
.ui-error{
  display:flex;align-items:flex-start;gap:var(--space-2);
  font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--fw-medium);
  color:var(--danger-strong);line-height:var(--leading-snug);
  background:var(--danger-bg);border:1px solid var(--danger-border);
  border-radius:var(--radius-xs);padding:.5rem .6875rem;
  animation:ui-error-in var(--dur-base) var(--ease-out);
}
.ui-error > i{color:var(--danger);font-size:var(--icon-sm);margin-top:.08rem;flex:none}
.ui-error strong{display:block;font-weight:var(--fw-semibold)}
.ui-error .ui-error-fix{display:block;font-weight:var(--fw-regular);color:var(--n-600);margin-top:.15rem}
@keyframes ui-error-in{
  from{opacity:0;transform:translateY(-4px)}
  to{opacity:1;transform:none}
}
.ui-error.is-leaving{animation:ui-error-out var(--dur-fast) var(--ease-out) forwards}
@keyframes ui-error-out{to{opacity:0;transform:translateY(-4px)}}

/* Nudges the invalid field once, so the eye lands on it. */
@keyframes ui-shake{
  10%,90%{transform:translateX(-1px)}
  20%,80%{transform:translateX(2px)}
  30%,50%,70%{transform:translateX(-3px)}
  40%,60%{transform:translateX(3px)}
}
.ui-shake{animation:ui-shake .45s var(--ease-in-out)}

/* ---- input with a leading icon and optional trailing button */
.ui-input-group{position:relative;display:flex;align-items:center}
.ui-input-group > .ui-input-icon{
  position:absolute;left:.8125rem;color:var(--n-400);font-size:var(--icon-sm);
  pointer-events:none;transition:color var(--dur-fast) var(--ease-out);
}
.ui-input-group:focus-within > .ui-input-icon{color:var(--red)}
.ui-input-group > .ui-input-icon ~ .ui-input{padding-left:2.4375rem}
.ui-input-affix{
  position:absolute;right:.375rem;display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;border:0;background:transparent;border-radius:var(--radius-xs);
  color:var(--n-500);cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast);
}
.ui-input-affix:hover{background:var(--n-100);color:var(--navy)}
.ui-input-affix:focus-visible{outline:none;box-shadow:0 0 0 2px var(--ring-color)}
.ui-input-group > .ui-input-affix ~ .ui-input,
.ui-input-group > .ui-input:has(~ .ui-input-affix){padding-right:2.75rem}

/* =====================================================================
   LICENCE KEY
   A technical value. It reads as one, and it is easy to select and copy.
   ===================================================================== */

.license-key{
  font-family:var(--font-mono);font-weight:var(--fw-semibold);
  letter-spacing:.04em;font-variant-numeric:tabular-nums;
}

.ui-key-input{
  font-family:var(--font-mono);font-weight:var(--fw-semibold);
  font-size:var(--text-md);letter-spacing:.12em;text-transform:uppercase;
  font-variant-numeric:tabular-nums;
  padding-block:.75rem;min-height:50px;
}
.ui-key-input::placeholder{letter-spacing:.1em;text-transform:none;font-weight:var(--fw-regular)}

/* The revealed key: large, selectable, with a copy affordance. */
.ui-key-reveal{
  display:flex;align-items:stretch;gap:var(--space-3);flex-wrap:wrap;
  background:var(--n-0);border:1px dashed var(--n-300);border-radius:var(--radius-md);
  padding:var(--space-4);
}
.ui-key-value{
  flex:1 1 320px;min-width:0;display:flex;align-items:center;
  font-family:var(--font-mono);font-weight:var(--fw-bold);
  font-size:clamp(.9rem,2.4vw,1.125rem);letter-spacing:.08em;
  color:var(--navy);font-variant-numeric:tabular-nums;
  overflow-x:auto;white-space:nowrap;user-select:all;-webkit-user-select:all;
  padding:var(--space-2) 0;
}
.ui-key-value::selection,.ui-key-value *::selection{background:var(--red-soft);color:var(--navy)}

/* Static display of a masked key inside tables. */
.ui-key-mask{
  font-family:var(--font-mono);font-size:var(--text-xs);letter-spacing:.03em;
  color:var(--n-500);white-space:nowrap;font-variant-numeric:tabular-nums;
}

/* =====================================================================
   CALLOUTS
   ===================================================================== */

.ui-callout{
  display:flex;gap:var(--space-3);align-items:flex-start;
  border:1px solid var(--line);border-left-width:3px;border-radius:var(--radius-sm);
  padding:var(--space-3) var(--space-4);
  font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-snug);
  color:var(--ink);background:var(--n-50);
}
.ui-callout > i{font-size:var(--icon-md);flex:none;margin-top:.05rem;color:var(--n-500)}
.ui-callout strong{display:block;font-family:var(--font-display);font-weight:var(--fw-semibold);margin-bottom:.15rem;color:var(--navy)}
.ui-callout-body{min-width:0}
.ui-callout.is-info{background:var(--info-bg);border-color:var(--info-border);border-left-color:var(--info)}
.ui-callout.is-info > i{color:var(--info)}
.ui-callout.is-success{background:var(--success-bg);border-color:var(--success-border);border-left-color:var(--success)}
.ui-callout.is-success > i{color:var(--success)}
.ui-callout.is-warning{background:var(--warning-bg);border-color:var(--warning-border);border-left-color:var(--warning)}
.ui-callout.is-warning > i{color:var(--warning)}
.ui-callout.is-danger{background:var(--danger-bg);border-color:var(--danger-border);border-left-color:var(--danger)}
.ui-callout.is-danger > i{color:var(--danger)}

/* =====================================================================
   BADGES
   ===================================================================== */

.ui-badge{
  display:inline-flex;align-items:center;gap:.3125rem;
  font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--fw-semibold);
  padding:.1875rem .5625rem;border-radius:var(--radius-full);
  background:var(--n-100);color:var(--n-600);white-space:nowrap;
  border:1px solid transparent;text-transform:capitalize;
}
.ui-badge::before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;opacity:.8}
.ui-badge.is-success{background:var(--success-bg);color:var(--success-strong);border-color:var(--success-border)}
.ui-badge.is-warning{background:var(--warning-bg);color:var(--warning-strong);border-color:var(--warning-border)}
.ui-badge.is-danger{background:var(--danger-bg);color:var(--danger-strong);border-color:var(--danger-border)}
.ui-badge.is-info{background:var(--info-bg);color:var(--info-strong);border-color:var(--info-border)}
.ui-badge.is-neutral{background:var(--n-100);color:var(--n-600);border-color:var(--n-200)}
.ui-badge.no-dot::before{display:none}

/* =====================================================================
   STEPS
   Communicates the shape of a flow: enter, validate, activate, done.
   ===================================================================== */

.ui-steps{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;list-style:none;margin:0;padding:0}
.ui-step{
  display:inline-flex;align-items:center;gap:var(--space-2);
  font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--fw-medium);
  color:var(--n-400);
}
.ui-step-num{
  width:22px;height:22px;border-radius:50%;display:grid;place-items:center;flex:none;
  background:var(--n-100);color:var(--n-500);font-size:var(--text-2xs);font-weight:var(--fw-bold);
  transition:background var(--dur-base) var(--ease-out),color var(--dur-base) var(--ease-out);
}
.ui-step.is-active{color:var(--navy)}
.ui-step.is-active .ui-step-num{background:var(--red);color:#fff}
.ui-step.is-done{color:var(--success)}
.ui-step.is-done .ui-step-num{background:var(--success-bg);color:var(--success)}
.ui-step-sep{width:18px;height:1px;background:var(--n-200);flex:none}

/* =====================================================================
   DIALOG
   One component for every confirmation, whatever the intent.
   ===================================================================== */

.ui-dialog-backdrop{
  position:fixed;inset:0;z-index:1200;
  display:flex;align-items:center;justify-content:center;padding:var(--space-4);
  background:rgba(10,19,48,.48);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;transition:opacity var(--dur-base) var(--ease-out);
  overflow-y:auto;
}
.ui-dialog-backdrop.is-open{opacity:1}

.ui-dialog{
  width:100%;max-width:460px;margin:auto;
  background:var(--n-0);border-radius:var(--radius-lg);box-shadow:var(--elev-4);
  transform:translateY(12px) scale(.97);opacity:0;
  transition:transform var(--dur-base) var(--ease-spring), opacity var(--dur-base) var(--ease-out);
  overflow:hidden;
}
.ui-dialog-backdrop.is-open .ui-dialog{transform:none;opacity:1}
.ui-dialog:focus{outline:none}

.ui-dialog-head{display:flex;gap:var(--space-4);align-items:flex-start;padding:var(--space-6) var(--space-6) var(--space-4)}
.ui-dialog-title{
  font-family:var(--font-display);font-size:var(--text-xl);font-weight:var(--fw-semibold);
  letter-spacing:var(--display-tracking);color:var(--navy);margin:0 0 var(--space-2);line-height:var(--leading-tight);
}
.ui-dialog-text{
  font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-normal);
  color:var(--n-600);margin:0;
}
.ui-dialog-text + .ui-dialog-text{margin-top:var(--space-2)}
.ui-dialog-body{min-width:0;flex:1}

/* The consequence line: what will actually happen, stated plainly. */
.ui-dialog-consequence{
  margin:var(--space-4) var(--space-6) 0;
  font-family:var(--font-body);font-size:var(--text-sm);line-height:var(--leading-snug);
  padding:var(--space-3) var(--space-4);border-radius:var(--radius-sm);
  background:var(--n-50);border-left:3px solid var(--n-300);color:var(--n-700);
}
.ui-dialog.is-danger .ui-dialog-consequence{background:var(--danger-bg);border-left-color:var(--danger);color:var(--danger-strong)}
.ui-dialog.is-warning .ui-dialog-consequence{background:var(--warning-bg);border-left-color:var(--warning);color:var(--warning-strong)}

.ui-dialog-foot{
  display:flex;gap:var(--space-2);justify-content:flex-end;flex-wrap:wrap;
  padding:var(--space-5) var(--space-6) var(--space-6);
}
.ui-dialog-foot .ui-btn{min-width:104px}
/* A third action pushes the pair right and sits on the left. */
.ui-dialog-foot .ui-dialog-tertiary{margin-right:auto}

.ui-dialog-close{
  position:absolute;top:var(--space-4);right:var(--space-4);
  width:32px;height:32px;border:0;background:transparent;border-radius:var(--radius-xs);
  color:var(--n-400);cursor:pointer;display:grid;place-items:center;font-size:var(--icon-sm);
  transition:background var(--dur-fast),color var(--dur-fast);
}
.ui-dialog-close:hover{background:var(--n-100);color:var(--navy)}
.ui-dialog-close:focus-visible{outline:none;box-shadow:0 0 0 2px var(--ring-color)}

/* Result shown in place once the action has run. */
.ui-dialog-result{display:flex;gap:var(--space-3);align-items:flex-start;padding:0 var(--space-6) var(--space-2)}
.ui-dialog-result.is-success{color:var(--success-strong)}
.ui-dialog-result.is-error{color:var(--danger-strong)}
.ui-dialog-result i{font-size:var(--icon-md);flex:none}

@media (max-width:479.98px){
  .ui-dialog-backdrop{padding:var(--space-3);align-items:flex-end}
  .ui-dialog{max-width:none;border-radius:var(--radius-lg) var(--radius-lg) 0 0;transform:translateY(24px)}
  .ui-dialog-head{padding:var(--space-5) var(--space-5) var(--space-3);gap:var(--space-3)}
  .ui-dialog-consequence{margin-inline:var(--space-5)}
  .ui-dialog-foot{padding:var(--space-4) var(--space-5) var(--space-5);flex-direction:column-reverse}
  .ui-dialog-foot .ui-btn{width:100%}
  .ui-dialog-foot .ui-dialog-tertiary{margin-right:0}
}

/* =====================================================================
   TOAST
   ===================================================================== */

.ui-toast-stack{
  position:fixed;top:var(--space-4);right:var(--space-4);z-index:1300;
  display:flex;flex-direction:column;gap:var(--space-2);
  width:min(380px,calc(100vw - 2rem));pointer-events:none;
}
.ui-toast{
  display:flex;gap:var(--space-3);align-items:flex-start;
  background:var(--n-0);border:1px solid var(--line);border-left:3px solid var(--n-400);
  border-radius:var(--radius-sm);box-shadow:var(--elev-3);
  padding:var(--space-3) var(--space-4);pointer-events:auto;
  font-family:var(--font-body);font-size:var(--text-base);color:var(--ink);
  transform:translateX(16px);opacity:0;
  transition:transform var(--dur-base) var(--ease-out),opacity var(--dur-base) var(--ease-out);
}
.ui-toast.is-open{transform:none;opacity:1}
.ui-toast.is-leaving{transform:translateX(16px);opacity:0}
.ui-toast > i{font-size:var(--icon-md);flex:none;margin-top:.05rem}
.ui-toast-body{flex:1;min-width:0;line-height:var(--leading-snug)}
.ui-toast-close{border:0;background:transparent;color:var(--n-400);cursor:pointer;font-size:var(--icon-sm);padding:0;flex:none}
.ui-toast-close:hover{color:var(--navy)}
.ui-toast.is-success{border-left-color:var(--success)}
.ui-toast.is-success > i{color:var(--success)}
.ui-toast.is-error{border-left-color:var(--danger)}
.ui-toast.is-error > i{color:var(--danger)}
.ui-toast.is-warning{border-left-color:var(--warning)}
.ui-toast.is-warning > i{color:var(--warning)}
.ui-toast.is-info{border-left-color:var(--info)}
.ui-toast.is-info > i{color:var(--info)}

@media (max-width:575.98px){
  .ui-toast-stack{top:auto;bottom:var(--space-3);left:var(--space-3);right:var(--space-3);width:auto}
  .ui-toast{transform:translateY(16px)}
  .ui-toast.is-leaving{transform:translateY(16px)}
}

/* =====================================================================
   SOUND PREFERENCE TOGGLE
   ===================================================================== */
.ui-sound-toggle{
  display:inline-flex;align-items:center;gap:var(--space-2);
  border:0;background:transparent;color:var(--n-400);cursor:pointer;
  font-family:var(--font-body);font-size:var(--text-xs);padding:.25rem .5rem;border-radius:var(--radius-xs);
  transition:color var(--dur-fast),background var(--dur-fast);
}
.ui-sound-toggle:hover{color:var(--navy);background:var(--n-100)}
.ui-sound-toggle:focus-visible{outline:none;box-shadow:0 0 0 2px var(--ring-color)}

/* =====================================================================
   UTILITIES
   ===================================================================== */
.ui-stack{display:flex;flex-direction:column}
.ui-stack-2{gap:var(--space-2)}
.ui-stack-3{gap:var(--space-3)}
.ui-stack-4{gap:var(--space-4)}
.ui-stack-6{gap:var(--space-6)}
.ui-row{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}
.ui-row-end{justify-content:flex-end}
.ui-grow{flex:1;min-width:0}
.ui-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;
}
[hidden]{display:none!important}
