﻿/* operandor design system — ported from design-system/ for Blazor.
   Every component value resolves to a semantic token so light/dark and
   theming stay a single-file change. Component prefix: .op- */

/* ---------------------------------------------------------------- fonts */
/* IBM Plex (SIL OFL 1.1, fontsource 5.1.1), self-hosted next to this stylesheet — no external CDN.
   Decision: each face comes in two files, basic Latin and Latin Extended, told apart by unicode-range.
   Why: the basic Latin file lacks ő and ű, and č, ć, đ, š and ž, so Hungarian, Croatian and Serbian text fell
   back to the system font for those letters; with unicode-range a browser loads the extended file only for a
   page that uses one of them, so the English pages load nothing more. The extended range leaves out ı, Œ and œ,
   which the basic file holds too; with them, the wordmark's dotless i made every page load it.
   Considered: one full font file per face, which every page would load; the basic files alone, which mixed two
   typefaces within a word. */
@font-face{font-family:"Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-sans-latin-ext-400-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Sans";font-style:italic;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-sans-latin-400-italic.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Sans";font-style:italic;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-sans-latin-ext-400-italic.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-sans-latin-ext-500-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-sans-latin-ext-600-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Serif";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-serif-latin-400-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Serif";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-serif-latin-ext-400-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Serif";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-serif-latin-600-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Serif";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/ibm-plex-serif-latin-ext-600-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/ibm-plex-mono-latin-ext-400-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/ibm-plex-mono-latin-ext-500-normal.woff2") format("woff2");unicode-range:U+0100-0130,U+0132-0151,U+0154-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* --------------------------------------------------------------- colors */
:root{
--green-50:#F1FBE6;--green-100:#DFF4C6;--green-200:#C0E794;--green-300:#93D051;
--green-400:#5EA905;--green-500:#3E891A;--green-600:#2D7612;--green-700:#216111;
--green-800:#164B10;--green-900:#0F380E;--green-950:#09250A;

--n-0:#FFFFFF;--n-50:#FAFBF9;--n-100:#F4F5F3;--n-200:#E8EAE6;--n-300:#D6D9D3;
--n-400:#A5AAA2;--n-500:#7F857C;--n-600:#636A61;--n-700:#4A5049;--n-800:#333833;
--n-900:#1C2126;--n-950:#14181C;

--slate-50:#F1F5F8;--slate-100:#DFE8EE;--slate-200:#BFD0DC;--slate-300:#94AEC0;
--slate-400:#648197;--slate-500:#3F5B72;--slate-600:#253645;--slate-700:#1E2C39;
--slate-800:#17222C;--slate-900:#111A22;--slate-950:#0B1118;
}

/* --------------------------------------------------------------- status */
:root{
--danger-50:#FCEFED;--danger-100:#F7D9D4;--danger-500:#B5342A;--danger-600:#9C2A21;
--danger-700:#7C2019;--danger-400:#E0675A;
--success-50:var(--green-50);--success-600:var(--green-600);--success-400:var(--green-400);
--info-50:var(--slate-50);--info-600:var(--slate-600);--info-400:var(--slate-400);
}

/* ----------------------------------------------------------- typography */
:root{
--font-heading:"Plex Sans","Söhne","Helvetica Neue",Helvetica,system-ui,sans-serif;
--font-body:"Plex Sans","Söhne","Helvetica Neue",Helvetica,system-ui,sans-serif;
--font-serif:"Plex Serif",Georgia,"Times New Roman",serif;
--font-mono:"Plex Mono","Berkeley Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

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

--fs-display:4.5rem;--fs-h1:3rem;--fs-h2:2.125rem;--fs-h3:1.375rem;--fs-h4:1.125rem;
--fs-body-lg:1.125rem;--fs-body:1rem;--fs-body-sm:0.875rem;--fs-caption:0.8125rem;--fs-micro:0.6875rem;

--lh-display:1.02;--lh-heading:1.14;--lh-body:1.6;--lh-tight:1.35;

--ls-display:-0.022em;--ls-heading:-0.014em;--ls-body:0em;--ls-label:0.01em;--ls-eyebrow:0.14em;--ls-mono:-0.005em;

--tt-eyebrow:uppercase;
}

/* -------------------------------------------------------------- spacing */
:root{
--sp-1:2px;--sp-2:4px;--sp-3:8px;--sp-4:12px;--sp-5:16px;--sp-6:24px;
--sp-7:32px;--sp-8:48px;--sp-9:64px;--sp-10:96px;--sp-11:128px;--sp-12:192px;

--measure-prose:64ch;--measure-narrow:46ch;--container-max:1200px;--container-text:760px;
--gutter:clamp(20px,5vw,64px);

--radius-0:0px;--radius-1:2px;--radius-2:4px;--radius-3:6px;--radius-4:10px;--radius-5:16px;--radius-full:999px;
--border-hairline:1px;--border-strong:1.5px;--border-focus:2px;
}

/* ------------------------------------------------------------ elevation */
:root{
--shadow-0:none;
--shadow-1:0 1px 2px rgba(20,24,28,0.05);
--shadow-2:0 1px 2px rgba(20,24,28,0.04),0 2px 8px rgba(20,24,28,0.06);
--shadow-3:0 2px 4px rgba(20,24,28,0.04),0 8px 24px rgba(20,24,28,0.08);
--shadow-4:0 4px 8px rgba(20,24,28,0.06),0 18px 48px rgba(20,24,28,0.12);
--shadow-inset-hairline:inset 0 0 0 1px rgba(20,24,28,0.06);
--shadow-1-dark:0 1px 2px rgba(0,0,0,0.4);
--shadow-2-dark:0 2px 8px rgba(0,0,0,0.45);
--shadow-3-dark:0 8px 24px rgba(0,0,0,0.5);
--shadow-4-dark:0 18px 48px rgba(0,0,0,0.55);
}

/* --------------------------------------------------------------- motion */
:root{
--dur-instant:80ms;--dur-fast:140ms;--dur-base:200ms;--dur-slow:320ms;--dur-deliberate:520ms;--dur-wordmark:2600ms;
--ease-standard:cubic-bezier(0.2,0,0,1);
--ease-exit:cubic-bezier(0.4,0,1,1);
--ease-inout:cubic-bezier(0.4,0,0.2,1);
--ease-linear:linear;
}
@media (prefers-reduced-motion:reduce){
:root{--dur-instant:0ms;--dur-fast:0ms;--dur-base:0ms;--dur-slow:0ms;--dur-deliberate:0ms;--dur-wordmark:0ms}
}

/* ------------------------------------------------------------ semantic */
:root,[data-theme="light"]{
--surface-page:var(--n-100);--surface-card:var(--n-0);--surface-sunken:var(--n-200);
--surface-raised:var(--n-0);--surface-inverse:var(--n-950);--surface-structural:var(--slate-600);
--surface-accent-tint:var(--green-50);--surface-hover:var(--n-200);--surface-active:var(--n-300);--surface-disabled:var(--n-200);

--text-heading:var(--n-950);--text-body:var(--n-800);--text-muted:var(--n-600);--text-subtle:var(--n-500);
--text-disabled:var(--n-400);--text-on-accent:var(--n-0);--text-on-inverse:var(--n-100);
--text-on-structural:var(--green-300);--text-on-accent-tint:var(--green-800);
--text-link:var(--green-600);--text-link-hover:var(--green-700);

--border-subtle:var(--n-200);--border-default:var(--n-300);--border-strong-c:var(--n-400);
--border-inverse:rgba(255,255,255,0.14);--border-accent:var(--green-600);

--accent:var(--green-600);--accent-hover:var(--green-700);--accent-active:var(--green-800);
--accent-quiet:var(--green-100);--brand-mark:var(--green-500);--focus-ring:var(--green-600);

--shadow-card:var(--shadow-1);--shadow-raised:var(--shadow-2);--shadow-overlay:var(--shadow-4);
--scrim:rgba(20,24,28,0.44);
}
html{color-scheme:light} :root{--text-danger:var(--danger-600)} @media (prefers-color-scheme:dark){:root:not([data-theme]){
--surface-page:var(--n-950);
--surface-card:#1C2126;
--surface-sunken:#101417;
--surface-raised:#232930;
--surface-inverse:var(--n-100);
--surface-structural:var(--slate-700);
--surface-accent-tint:rgba(94,169,5,0.12);
--surface-hover:rgba(255,255,255,0.06);
--surface-active:rgba(255,255,255,0.10);
--surface-disabled:rgba(255,255,255,0.06);

--text-heading:var(--n-50);
--text-body:#D8DCD7;
--text-muted:#A5AAA2;
--text-subtle:#8B918A;
--text-disabled:#5C635C;
--text-on-accent:var(--n-950);
--text-on-inverse:var(--n-950);
--text-on-structural:var(--green-300);
--text-on-accent-tint:var(--green-300);
--text-link:var(--green-400);
--text-link-hover:var(--green-300);

--border-subtle:rgba(255,255,255,0.10);
--border-default:rgba(255,255,255,0.16);
--border-strong-c:rgba(255,255,255,0.28);
--border-inverse:rgba(20,24,28,0.14);
--border-accent:var(--green-400);

--accent:var(--green-400);
--accent-hover:var(--green-300);
--accent-active:var(--green-200);
--accent-quiet:rgba(94,169,5,0.18);
--brand-mark:var(--green-400);
--focus-ring:var(--green-400);

--shadow-card:var(--shadow-1-dark);
--shadow-raised:var(--shadow-2-dark);
--shadow-overlay:var(--shadow-4-dark);
--scrim:rgba(0,0,0,0.62);
color-scheme:dark;--text-danger:var(--danger-400)}}

/* Explicit user choice. With no data-theme attribute, the media query above
   remains the source of truth (the System option). */
:root[data-theme="dark"]{
--surface-page:var(--n-950);--surface-card:#1C2126;--surface-sunken:#101417;--surface-raised:#232930;--surface-inverse:var(--n-100);--surface-structural:var(--slate-700);--surface-accent-tint:rgba(94,169,5,0.12);--surface-hover:rgba(255,255,255,0.06);--surface-active:rgba(255,255,255,0.10);--surface-disabled:rgba(255,255,255,0.06);
--text-heading:var(--n-50);--text-body:#D8DCD7;--text-muted:#A5AAA2;--text-subtle:#8B918A;--text-disabled:#5C635C;--text-on-accent:var(--n-950);--text-on-inverse:var(--n-950);--text-on-structural:var(--green-300);--text-on-accent-tint:var(--green-300);--text-link:var(--green-400);--text-link-hover:var(--green-300);
--border-subtle:rgba(255,255,255,0.10);--border-default:rgba(255,255,255,0.16);--border-strong-c:rgba(255,255,255,0.28);--border-inverse:rgba(20,24,28,0.14);--border-accent:var(--green-400);
--accent:var(--green-400);--accent-hover:var(--green-300);--accent-active:var(--green-200);--accent-quiet:rgba(94,169,5,0.18);--brand-mark:var(--green-400);--focus-ring:var(--green-400);
--shadow-card:var(--shadow-1-dark);--shadow-raised:var(--shadow-2-dark);--shadow-overlay:var(--shadow-4-dark);--scrim:rgba(0,0,0,0.62);color-scheme:dark;--text-danger:var(--danger-400)}

/* ------------------------------------------------------------- base */
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0}
body{
  background:var(--surface-page);
  color:var(--text-body);
  font-family:var(--font-body);
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
h1,h2,h3{text-wrap:pretty}
a{color:var(--text-link);text-decoration:none}
a:hover{color:var(--text-link-hover)}
:focus-visible{outline:var(--border-focus) solid var(--focus-ring);outline-offset:2px}

/* ---------------------------------------------------------------- button */
.op-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-3);font-family:var(--font-body);font-weight:var(--fw-medium);letter-spacing:var(--ls-label);border:1px solid transparent;border-radius:var(--radius-2);cursor:pointer;text-decoration:none;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-instant) var(--ease-standard)}
.op-btn:focus-visible{outline:var(--border-focus) solid var(--focus-ring);outline-offset:2px}
.op-btn:active{transform:translateY(0.5px)}
.op-btn--sm{height:32px;padding:0 var(--sp-4);font-size:var(--fs-caption)}
.op-btn--md{height:40px;padding:0 var(--sp-5);font-size:var(--fs-body-sm)}
.op-btn--lg{height:48px;padding:0 var(--sp-6);font-size:var(--fs-body)}
.op-btn--primary{background:var(--accent);color:var(--text-on-accent)}
.op-btn--primary:hover{background:var(--accent-hover);color:var(--text-on-accent)}
.op-btn--primary:active{background:var(--accent-active)}
.op-btn--secondary{background:var(--surface-structural);color:var(--n-0)}
.op-btn--secondary:hover{background:var(--slate-700);color:var(--n-0)}
.op-btn--secondary:active{background:var(--slate-800)}
.op-btn--outline{background:transparent;color:var(--text-heading);border-color:var(--border-default)}
.op-btn--outline:hover{background:var(--surface-hover);border-color:var(--border-strong-c);color:var(--text-heading)}
.op-btn--outline.op-btn--on-dark{color:#fff;border-color:rgba(255,255,255,0.3)}
.op-btn--outline.op-btn--on-dark:hover{background:rgba(255,255,255,0.14);border-color:rgba(255,255,255,0.65);color:#fff}
.op-btn--outline.op-btn--on-dark:active{background:rgba(255,255,255,0.22)}
.op-btn--ghost{background:transparent;color:var(--text-link)}
.op-btn--ghost:hover{background:var(--surface-accent-tint);color:var(--text-link)}
.op-btn--danger{background:var(--danger-600);color:var(--n-0)}
.op-btn--danger:hover{background:var(--danger-700)}
.op-btn:disabled,.op-btn[aria-disabled="true"]{background:var(--surface-disabled);color:var(--text-disabled);border-color:transparent;cursor:not-allowed;transform:none}
.op-btn--block{width:100%}

/* ------------------------------------------------------------ text link */
/* OpTextLink: reads as text and wraps like it; its last word and arrow never part. */
.op-text-link{display:inline;color:var(--text-link);font-weight:var(--fw-medium);font-size:15px;line-height:1.5;text-decoration:none}
.op-text-link:hover{text-decoration:underline;text-underline-offset:3px}
.op-text-link.op-text-link--on-dark{color:var(--green-300)}
.op-text-link__end{white-space:nowrap}
.op-text-link__end .op-icon{margin-left:8px;vertical-align:middle}

/* -------------------------------------------------------------- iconbtn */
.op-iconbtn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:1px solid transparent;border-radius:var(--radius-2);color:var(--text-muted);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard)}
.op-iconbtn:hover{background:var(--surface-hover);color:var(--text-heading)}
.op-iconbtn:focus-visible{outline:var(--border-focus) solid var(--focus-ring);outline-offset:2px}
.op-iconbtn--sm{width:32px;height:32px}
.op-iconbtn--md{width:40px;height:40px}
.op-iconbtn--outline{border-color:var(--border-default)}
.op-iconbtn:disabled{color:var(--text-disabled);cursor:not-allowed}

/* --------------------------------------------------------------- badge */
.op-badge{display:inline-flex;align-items:center;gap:var(--sp-2);font-family:var(--font-body);font-size:var(--fs-micro);font-weight:var(--fw-medium);letter-spacing:var(--ls-eyebrow);text-transform:uppercase;padding:3px var(--sp-3) 2px;border-radius:var(--radius-1);border:1px solid transparent}
.op-badge--accent{background:var(--surface-accent-tint);color:var(--text-on-accent-tint)}
.op-badge--neutral{background:var(--surface-sunken);color:var(--text-muted)}
.op-badge--outline{border-color:var(--border-default);color:var(--text-muted)}
.op-badge--danger{background:var(--danger-50);color:var(--danger-700)}
.op-badge--solid{background:var(--accent);color:var(--text-on-accent)}

/* ----------------------------------------------------------------- tag */
.op-tag{display:inline-flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-caption);color:var(--text-body);background:var(--surface-card);border:1px solid var(--border-subtle);border-radius:var(--radius-2);padding:4px var(--sp-3);font-family:var(--font-mono);letter-spacing:var(--ls-mono)}
.op-tag--removable{padding-right:var(--sp-2)}
.op-tag__x{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border:0;background:transparent;color:var(--text-subtle);cursor:pointer;border-radius:var(--radius-1)}
.op-tag__x:hover{background:var(--surface-hover);color:var(--text-heading)}

/* ---------------------------------------------------------------- card */
.op-card{background:var(--surface-card);border:1px solid var(--border-subtle);border-radius:var(--radius-3);box-shadow:var(--shadow-card)}
.op-card--flat{box-shadow:none}
.op-card--raised{box-shadow:var(--shadow-raised)}
.op-card--structural{background:var(--surface-structural);border-color:transparent;color:var(--n-0)}
.op-card--pad-md{padding:var(--sp-6)}
.op-card--pad-lg{padding:var(--sp-7)}
.op-card--pad-none{padding:0}
.op-card--interactive{cursor:pointer;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard)}
.op-card--interactive:hover{border-color:var(--border-accent);box-shadow:var(--shadow-raised);transform:translateY(-1px)}
/* A card that is one link (OpCard Href): its text keeps the card's colours, and its cue shows where it leads. */
.op-card--link{display:block;color:inherit;text-decoration:none;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard)}
.op-card--link:hover{color:inherit;border-color:var(--border-accent);box-shadow:var(--shadow-raised);transform:translateY(-1px)}
.op-card--link:focus-visible{border-color:var(--border-accent)}
.op-card__cue{display:inline-flex;align-items:center;gap:var(--sp-3);color:var(--text-link);font-weight:var(--fw-medium);font-size:15px;line-height:1.5}
.op-card--link:hover .op-card__cue{color:var(--text-link-hover);text-decoration:underline;text-underline-offset:3px}
@media (prefers-reduced-motion:reduce){.op-card--interactive:hover,.op-card--link:hover{transform:none}}

/* ---------------------------------------------------------------- stat */
.op-stat__label{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:var(--ls-eyebrow);color:var(--text-muted);font-weight:var(--fw-medium)}
.op-stat__value{font-family:var(--font-mono);font-size:32px;letter-spacing:-0.02em;color:var(--text-heading);line-height:1.1;margin-top:var(--sp-3)}
.op-stat__hint{font-size:var(--fs-caption);color:var(--text-muted);margin-top:var(--sp-2)}

/* --------------------------------------------------------------- field */
.op-field{display:flex;flex-direction:column;gap:var(--sp-3)}
.op-field__label{font-size:var(--fs-body-sm);font-weight:var(--fw-medium);letter-spacing:var(--ls-label);color:var(--text-heading)}
.op-field__req{color:var(--accent);margin-left:2px}
.op-field__hint{font-size:var(--fs-caption);color:var(--text-muted)}
.op-field__error{font-size:var(--fs-caption);color:var(--text-danger)}

.op-input,.op-textarea,.op-select{width:100%;box-sizing:border-box;font-family:var(--font-body);font-size:var(--fs-body-sm);color:var(--text-heading);background:var(--surface-card);border:1px solid var(--border-default);border-radius:var(--radius-2);padding:0 var(--sp-4);height:40px;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard)}
.op-textarea{height:auto;padding:var(--sp-4);line-height:var(--lh-body);resize:vertical}
.op-input::placeholder,.op-textarea::placeholder{color:var(--text-disabled)}
.op-input:hover,.op-textarea:hover,.op-select:hover{border-color:var(--border-strong-c)}
.op-input:focus,.op-textarea:focus,.op-select:focus{outline:none;border-color:var(--border-accent);box-shadow:0 0 0 3px var(--accent-quiet)}
.op-input--invalid,.op-textarea--invalid,.op-select--invalid{border-color:var(--danger-500)}
.op-input--invalid:focus{box-shadow:0 0 0 3px var(--danger-50)}
.op-input:disabled,.op-textarea:disabled,.op-select:disabled{background:var(--surface-disabled);color:var(--text-disabled);cursor:not-allowed}
.op-input--mono{font-family:var(--font-mono);letter-spacing:var(--ls-mono)}
.op-select{appearance:none;padding-right:var(--sp-7);background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);background-position:calc(100% - 18px) 17px,calc(100% - 12px) 17px;background-size:6px 6px,6px 6px;background-repeat:no-repeat}

/* --------------------------------------------------------- check/radio */
.op-check,.op-radio{display:inline-flex;align-items:flex-start;gap:var(--sp-3);font-size:var(--fs-body-sm);color:var(--text-body);cursor:pointer}
.op-check__box,.op-radio__box{flex:0 0 auto;width:18px;height:18px;margin-top:1px;border:1.5px solid var(--border-strong-c);background:var(--surface-card);display:inline-flex;align-items:center;justify-content:center;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
.op-check__box{border-radius:var(--radius-1)}
.op-radio__box{border-radius:var(--radius-full)}
.op-check:hover .op-check__box,.op-radio:hover .op-radio__box{border-color:var(--accent)}
.op-check--on .op-check__box{background:var(--accent);border-color:var(--accent)}
.op-radio--on .op-radio__box{border-color:var(--accent);border-width:5px}
.op-check__mark{width:11px;height:11px;color:var(--text-on-accent)}
.op-check input,.op-radio input{position:absolute;opacity:0;width:0;height:0}
.op-check input:focus-visible+.op-check__box,.op-radio input:focus-visible+.op-radio__box{outline:var(--border-focus) solid var(--focus-ring);outline-offset:2px}
.op-check--disabled,.op-radio--disabled{color:var(--text-disabled);cursor:not-allowed}

/* -------------------------------------------------------------- callout */
.op-callout{display:flex;gap:var(--sp-4);padding:var(--sp-5);border-radius:var(--radius-3);border:1px solid var(--border-subtle);background:var(--surface-card);font-size:var(--fs-body-sm);line-height:var(--lh-body);color:var(--text-body)}
.op-callout__icon{flex:0 0 auto;margin-top:1px}
.op-callout__title{font-weight:var(--fw-semibold);color:var(--text-heading);margin-bottom:2px}
.op-callout--accent{background:var(--surface-accent-tint);border-color:var(--green-200);color:var(--text-on-accent-tint)}
.op-callout--accent .op-callout__title{color:var(--text-on-accent-tint)}
.op-callout--danger{background:var(--danger-50);border-color:var(--danger-100);color:var(--danger-700)}
.op-callout--danger .op-callout__title{color:var(--danger-700)}
.op-callout--info{background:var(--info-50);border-color:var(--slate-200);color:var(--slate-700)}

/* ------------------------------------------------------- dialog / toast */
/* OpDialog is a native <dialog> shown with showModal: the browser centres it in the top layer and draws ::backdrop. */
.op-dialog{background:var(--surface-card);color:inherit;border:1px solid var(--border-subtle);border-radius:var(--radius-4);box-shadow:var(--shadow-overlay);padding:0;width:calc(100% - 2 * var(--sp-6));max-width:480px;max-height:calc(100% - 2 * var(--sp-6));overflow:auto;animation:op-rise var(--dur-slow) var(--ease-standard)}
.op-dialog::backdrop{background:var(--scrim,rgba(20,24,28,0.44));animation:op-fade var(--dur-base) var(--ease-standard)}
/* A dialog shown without its script (OpDialog) is not modal, so the browser neither centres it nor puts it in
   the top layer: it is placed where a modal one would be, above the header, the consent panel and the toast. */
.op-dialog--inline{position:fixed;inset:0;margin:auto;height:fit-content;z-index:60}
.op-dialog__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-5);padding:var(--sp-6) var(--sp-6) 0}
.op-dialog__title{font-family:var(--font-heading);font-size:var(--fs-h3);font-weight:var(--fw-semibold);letter-spacing:var(--ls-heading);color:var(--text-heading)}
.op-dialog__body{padding:var(--sp-4) var(--sp-6) var(--sp-6);font-size:var(--fs-body-sm);line-height:var(--lh-body);color:var(--text-muted)}
.op-dialog__foot{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--sp-3);padding:var(--sp-5) var(--sp-6);border-top:1px solid var(--border-subtle)}
/* Decision: on a phone the dialog's actions stack at full width, the last one (the main action) on top.
   Why: a row of three actions does not fit 375px once a label is translated ("Az összes elfogadása"), and
   a wrapped row leaves buttons of odd widths at odd places.
   Considered: wrapping only, which breaks the row at a different place in every language; shorter labels,
   which would bend the copy to the layout. */
@media (max-width:480px){
  .op-dialog__foot{flex-direction:column-reverse;align-items:stretch}
}
/* While ConsentDialog's first-visit panel covers the bottom of the screen, the browser scrolls a focused element
   above it, and the end of the page can be scrolled above it too. The space is the panel's tallest measured
   height with its inset (about 190px on wide screens, 260px at 320px wide, in the longest language) and a margin.
   Here and not in the component's scoped CSS, whose rewrite cannot reach html or body. */
html:has(.op-consent){--op-consent-space:208px;scroll-padding-bottom:var(--op-consent-space)}
html:has(.op-consent) body{padding-bottom:var(--op-consent-space)}
@media (max-width:768px){html:has(.op-consent){--op-consent-space:272px}}
@keyframes op-fade{from{opacity:0}to{opacity:1}}
@keyframes op-rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ToastHost's corner of the screen.
   Decision: while the first-visit consent panel is on screen, the toast sits above it.
   Why: both are fixed to the bottom of the screen and the toast is on top, so it covered the panel's buttons, all
   three on a phone, until the visitor dismissed it. --op-consent-space is the room the page already keeps for the
   panel; without the panel it is not set and the toast is in the corner.
   Considered: the toast under the panel, which hides the outcome of a send; a timeout on the toast, which takes an
   error away before it is read.
   Decision: the region reaches from under the header down to that place, and the toast sits at its lower end by
   an auto margin.
   Why: on a short screen, a phone in landscape, the room above the panel is less than the toast is tall. Placed
   from the bottom alone, the toast was pushed off the top of the screen with its title and its dismiss button,
   and nothing scrolls a fixed element back. An auto margin is nothing when there is no room, so the toast then
   starts under the header and lies over part of the panel, where it can be read and dismissed; one taller than
   the screen scrolls inside. The region itself lets clicks through.
   Considered: a rule by screen height, which needs the toast's height in every language; the corner on short
   screens, which again covers all of the panel's buttons. */
.op-toasts{position:fixed;top:88px;right:24px;bottom:calc(24px + var(--op-consent-space,0px));display:flex;flex-direction:column;pointer-events:none;z-index:50}
.op-toasts>.op-toast{flex:0 0 auto;margin-top:auto;pointer-events:auto;max-height:calc(100vh - 112px);max-height:calc(100dvh - 112px);overflow-y:auto}
.op-toast{display:flex;align-items:flex-start;gap:var(--sp-4);background:var(--surface-inverse);color:var(--text-on-inverse);border-radius:var(--radius-3);box-shadow:var(--shadow-overlay);padding:var(--sp-4) var(--sp-5);font-size:var(--fs-body-sm);max-width:420px;animation:op-rise var(--dur-slow) var(--ease-standard)}
.op-toast__title{font-weight:var(--fw-semibold)}
.op-toast__msg{opacity:0.78;margin-top:2px}
.op-toast--accent .op-toast__icon{color:var(--green-300)}
.op-toast--danger .op-toast__icon{color:var(--danger-400)}
.op-toast__x{margin-left:auto;background:transparent;border:0;color:currentColor;opacity:0.6;cursor:pointer;padding:0}
.op-toast__x:hover{opacity:1}

/* --------------------------------------------------------- breadcrumbs */
.op-crumbs{display:flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-caption);color:var(--text-muted);flex-wrap:wrap}
.op-crumbs a{color:var(--text-muted);text-decoration:none}
.op-crumbs a:hover{color:var(--text-link)}
.op-crumbs__sep{color:var(--text-disabled)}
.op-crumbs__current{color:var(--text-heading)}

/* --------------------------------------------------------------- prose */
/* OpProse: running text from plain elements, such as an article rendered from Markdown. The sizes are the case
   study pages' (17px on a 1.7 line, 24px section headings), so an article reads like the pages around it.
   Decision: links in the text are underlined.
   Why: inside a paragraph a link has to be told from the text by more than its colour; the site's other links stand
   alone, where the colour is enough.
   Decision: strong text is the semibold weight the fonts ship.
   Why: the browser's default is bold (700), which Plex Sans is not loaded in, so it would be drawn by thickening
   the 600 weight.
   Decision: a table keeps whole words, and its box (op-prose__scroll) scrolls sideways when the table is wider.
   Why: a band lets a long word break anywhere so it cannot widen a phone's page; inside a table that would narrow
   every column to a letter instead of letting the table scroll.
   Decision: a figure stands apart from the paragraphs around it, its image has a hairline border, and its caption
   is small, muted text right under the image.
   Why: the caption belongs to the image and must not read as the next paragraph; an image that brings its own dark
   surface needs an edge on the dark page, where it would otherwise run into the background.
   Considered: a card around the figure, a second frame around an image that is a panel already; the caption in
   the body's size and colour, which reads as the text going on. */
.op-prose{max-width:var(--measure-prose);font-size:17px;line-height:1.7;color:var(--text-body);overflow-wrap:break-word}
.op-prose > :first-child{margin-top:0}
.op-prose > :last-child{margin-bottom:0}
.op-prose p,.op-prose ul,.op-prose ol,.op-prose pre,.op-prose__scroll{margin:0 0 18px}
.op-prose h2,.op-prose h3,.op-prose h4{font-family:var(--font-heading);font-weight:var(--fw-semibold);letter-spacing:var(--ls-heading);color:var(--text-heading);scroll-margin-top:88px}
.op-prose h2{font-size:24px;line-height:1.25;margin:40px 0 14px}
.op-prose h3{font-size:19px;line-height:1.3;margin:32px 0 10px}
.op-prose h4{font-size:17px;line-height:1.4;margin:24px 0 8px}
.op-prose a{color:var(--text-link);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.op-prose a:hover{color:var(--text-link-hover)}
.op-prose strong{font-weight:var(--fw-semibold);color:var(--text-heading)}
.op-prose ul,.op-prose ol{padding-left:1.4em}
.op-prose li{margin:0 0 6px}
.op-prose li > ul,.op-prose li > ol{margin:6px 0 0}
.op-prose li::marker{color:var(--text-subtle)}
.op-prose blockquote{margin:28px 0;padding-left:20px;border-left:2px solid var(--accent);font-family:var(--font-serif);font-size:19px;line-height:1.5;color:var(--text-heading)}
.op-prose blockquote > :last-child{margin-bottom:0}
.op-prose code{font-family:var(--font-mono);font-size:0.9em;letter-spacing:var(--ls-mono);background:var(--surface-sunken);border-radius:var(--radius-1);padding:1px 5px}
.op-prose pre{background:var(--surface-sunken);border:1px solid var(--border-subtle);border-radius:var(--radius-3);padding:var(--sp-5);overflow-x:auto;font-size:14px;line-height:1.6}
.op-prose pre code{background:none;border-radius:0;padding:0;font-size:inherit;white-space:pre}
.op-prose__scroll{overflow-x:auto;border:1px solid var(--border-subtle);border-radius:var(--radius-3);background:var(--surface-card)}
.op-prose table{width:100%;border-collapse:collapse;font-size:15px;line-height:1.5;overflow-wrap:normal}
.op-prose th,.op-prose td{padding:10px 14px;text-align:left;vertical-align:top;border-bottom:1px solid var(--border-subtle)}
.op-prose th{font-weight:var(--fw-semibold);color:var(--text-heading);background:var(--surface-sunken);white-space:nowrap}
.op-prose tbody tr:last-child td{border-bottom:0}
.op-prose img{display:block;max-width:100%;height:auto;border-radius:var(--radius-3)}
.op-prose figure{margin:28px 0}
.op-prose figure img{border:var(--border-hairline) solid var(--border-subtle)}
.op-prose figcaption{margin-top:var(--sp-4);font-size:var(--fs-body-sm);line-height:1.5;color:var(--text-muted)}
.op-prose hr{border:0;border-top:1px solid var(--border-subtle);margin:32px 0}

/* --------------------------------------------------------------- icon */
.op-icon{display:inline-block;flex:0 0 auto;background:currentColor;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-position:center;mask-position:center}

/* ----------------------------------------------------- site chrome */
.op-band{position:relative;padding:var(--band-padding,96px) var(--gutter)}
.op-band__inner{max-width:var(--container-max);margin:0 auto;position:relative}
.op-band--page{background:var(--surface-page)}
.op-band--card{background:var(--surface-card)}
.op-band--structural{background:var(--slate-600)}
.op-band--dark{background:var(--n-950)}

.op-eyebrow{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:0.14em;color:var(--accent)}
.op-eyebrow--dark{color:var(--green-300)}

.op-wordmark{line-height:1}
.op-wordmark__dot{color:var(--brand-mark)}
.op-wordmark__i{position:relative;display:inline-block;line-height:1}
.op-wordmark__i::before{content:"";position:absolute;left:0.137em;transform:translateX(-50%);top:0.14em;width:0.15em;height:0.15em;border-radius:50%;background:var(--brand-mark)}

.op-field-mark{position:absolute;inset:0;-webkit-mask-image:url("mark-f.svg");mask-image:url("mark-f.svg");-webkit-mask-repeat:repeat;mask-repeat:repeat}

.op-header{position:sticky;top:0;z-index:30;background:var(--surface-card);border-bottom:1px solid var(--border-subtle)}
.op-header__inner{max-width:var(--container-max);margin:0 auto;padding:0 var(--gutter);height:72px;display:flex;align-items:center;gap:40px}
.op-header__nav{display:flex;gap:28px;margin-left:8px}
.op-nav-link{font-size:14px;font-weight:500;letter-spacing:0.01em;text-decoration:none;padding-bottom:2px;color:var(--text-muted);border-bottom:2px solid transparent;white-space:nowrap}
.op-nav-link:hover{color:var(--text-heading)}
.op-nav-link.active{color:var(--text-heading);border-bottom-color:var(--accent)}
.op-header__home{display:flex;align-items:center;flex-shrink:0;min-width:0;text-decoration:none}
.op-header__right{margin-left:auto;display:flex;align-items:center;gap:14px;min-width:0}
.op-header__right .op-btn{flex-shrink:0;white-space:nowrap;max-width:100%}
.op-header__menu{display:none;flex-shrink:0}
.op-header__toggle{list-style:none;cursor:pointer}
.op-header__toggle::-webkit-details-marker{display:none}
.op-header__menu:not([open]) .op-header__icon-close,.op-header__menu[open] .op-header__icon-open{display:none}
.op-header__lang{display:flex;align-items:center}

/* Hidden on screen, read by screen readers: a name for a control whose visible label is partial. */
.op-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}

.op-langmenu{position:relative}
.op-langmenu__button{display:inline-flex;align-items:center;gap:6px;list-style:none;cursor:pointer;font-size:14px;font-weight:500;letter-spacing:0.01em;color:var(--text-muted);padding:6px 8px;border-radius:var(--radius-2)}
.op-langmenu__button::-webkit-details-marker{display:none}
.op-langmenu__button:hover,.op-langmenu[open] .op-langmenu__button{color:var(--text-heading)}
.op-langmenu[open] .op-langmenu__button{background:var(--surface-hover)}
/* The list hangs from its button: its left edge under the button's, its notch pointing at the icon
   (8px padding + half of the 18px icon), and it drops from there. */
.op-langmenu__list{position:absolute;top:calc(100% + 8px);left:0;min-width:160px;margin:0;padding:6px 0;list-style:none;background:var(--surface-card);border:1px solid var(--border-default);border-radius:var(--radius-3);box-shadow:var(--shadow-raised);z-index:31;transform-origin:17px 0;animation:op-drop var(--dur-fast) var(--ease-standard)}
.op-langmenu__list::before{content:"";position:absolute;top:-6px;left:12px;width:10px;height:10px;background:var(--surface-card);border-top:1px solid var(--border-default);border-left:1px solid var(--border-default);transform:rotate(45deg)}
@keyframes op-drop{from{opacity:0;transform:translateY(-4px) scaleY(0.96)}to{opacity:1;transform:none}}
.op-langmenu__link{display:block;padding:8px 16px;font-size:14px;color:var(--text-body);text-decoration:none}
.op-langmenu__link:hover{background:var(--surface-hover);color:var(--text-heading)}
.op-langmenu__link[aria-current="true"]{color:var(--text-heading);font-weight:600}

.op-footer{background:var(--n-950);padding:72px var(--gutter) 32px;position:relative;overflow:hidden}
.op-footer__inner{max-width:var(--container-max);margin:0 auto;position:relative}
.op-footer__cols{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:48px}
.op-footer__coltitle{font-size:11px;text-transform:uppercase;letter-spacing:0.14em;color:var(--green-300);font-weight:500}
.op-footer__links{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.op-footer__links a{font-size:14px;color:rgba(255,255,255,0.72);text-decoration:none}
.op-footer__links a:hover{color:#fff}
.op-footer__links--mono{font-family:var(--font-mono);font-size:13px;color:rgba(255,255,255,0.72)}
.op-footer__after{margin-top:18px}
.op-footer__bottom{display:flex;justify-content:space-between;align-items:center;gap:20px;margin-top:56px;padding-top:24px;border-top:1px solid rgba(255,255,255,0.12);font-size:12px;color:rgba(255,255,255,0.55);font-family:var(--font-mono)}
.op-footer__utility{display:flex;align-items:center;gap:10px}
.op-footer__icon-button{display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;padding:0;border:1px solid transparent;border-radius:var(--radius-2);background:transparent;color:rgba(255,255,255,0.58);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard)}
.op-footer__icon-button:hover{background:rgba(255,255,255,0.1);color:#fff}
.op-footer__icon-button:focus-visible{outline:var(--border-focus) solid var(--green-300);outline-offset:2px}

/* --------------------------------------------------------- responsive */
/* Decision: the header folds its links and the language menu into the menu button up to 1180px, not 900px.
   Why: the Hungarian links ("Szakmai tapasztalat" the longest), the language menu and the short call to action
   need about 1165px in one row; below that a link broke into two lines or the row ran past the right edge.
   Considered: tighter gaps between the links, which still left Hungarian and Croatian 40–80px over at 901–960px;
   the language menu without its name, which leaves it without a visible label; a shorter Hungarian label, which
   the copy does not allow. */
@media (max-width:1180px){
  .op-header__inner{gap:20px}
  .op-header__nav{display:none}
  .op-header__menu{display:block}
  /* Decision: the panel is at most as tall as the screen below the header, and scrolls inside.
     Why: the header is sticky, so the panel does not move with the page: on a short screen, such as a phone in
     landscape, the end of the open language list was below the screen and could not be reached. dvh follows the
     browser's own bars; vh is for browsers without it.
     Considered: a header that is not sticky while the menu is open, which scrolls the menu button away. */
  .op-header__panel{display:flex;flex-direction:column;position:absolute;top:72px;left:0;right:0;max-height:calc(100vh - 72px);max-height:calc(100dvh - 72px);overflow-y:auto;overscroll-behavior:contain;background:var(--surface-card);border-bottom:1px solid var(--border-subtle);box-shadow:var(--shadow-raised);padding:8px var(--gutter) 16px;z-index:29}
  .op-header__panel .op-nav-link{padding:14px 0;border-bottom:0}
  .op-header__lang--menu{border-top:1px solid var(--border-subtle);margin-top:8px}
  .op-header__lang--menu .op-langmenu{width:100%}
  .op-header__lang--menu .op-langmenu__button{padding:14px 0}
  .op-header__lang--menu .op-langmenu[open] .op-langmenu__button{background:none}
  .op-header__lang--menu .op-langmenu__list{position:static;min-width:0;padding:0 0 8px;border:0;border-radius:0;box-shadow:none;background:none;animation:none}
  .op-header__lang--menu .op-langmenu__list::before{display:none}
  .op-header__lang--menu .op-langmenu__link{padding:10px 0 10px 24px}
  .op-header__lang--bar{display:none}
  .op-header__toggle{display:inline-flex}
  .op-header__right{gap:8px}
}
@media (max-width:900px){
  .op-footer__cols{grid-template-columns:1fr 1fr;gap:32px}
}
@media (max-width:640px){
  .op-header__inner{gap:12px}
  .op-header__right{gap:8px}
  .op-header__right .op-btn{height:30px;padding:0 12px;font-size:11px}
  .op-footer__cols{grid-template-columns:1fr}
  .op-band{padding:64px var(--gutter)}
}
/* Decision: the collapsed header gives way in three steps and keeps the page's gutter at every width. Up to 420px
   the call to action drops its arrow, and the button and the gaps narrow; up to 384px the menu button is 32px, and
   the button and the gaps narrow once more; up to 370px the call to action is hidden.
   Why: nothing in the row shrinks (the logo is 170px wide, the label does not wrap), so these widths alone decide
   whether the row fits. With the longest label of operandor.io ("Zatražite razgovor", a 115px button at 11px) the
   row needs 373px with the arrow, 341px without it and 325px in the tightest step, which the page's column gives
   from 415px, 382px and 366px. The steps were at 400px and 360px, set for a button of about 108px, so the menu
   button ran up to 20px past the column at 361–381px and up to 12px at 401–414px in Hungarian, Croatian and
   Serbian, and up to 10px in English with "Request a demo". Each step now leaves at least 3px to spare where it
   ends, for a browser that sets the label a little wider; a label longer than about 18 characters needs wider steps.
   Up to 360px the header had 14px at its sides in place of the gutter, which the row never needed (212px of 280px):
   the logo stood 6px left of the page's text and the menu button 6px right of it.
   Considered: hiding the button up to 384px, which drops the call to action on 375px phones; the steps in the
   site's own stylesheet, sized to its labels, which leaves the row overflowing with a shorter label too and the
   steps in two files; a smaller logo, whose size is set inline; a label that is cut off, which reads as a mistake;
   a narrower gutter, which moves the logo out of line with the page's text. */
@media (max-width:420px){
  .op-header__inner{gap:10px}
  .op-header__right{gap:6px}
  .op-header__right .op-btn{padding:0 10px}
  .op-header__right .op-btn .op-icon{display:none}
}
@media (max-width:384px){
  .op-header__inner{gap:8px}
  .op-header__right{gap:4px}
  .op-header__right .op-btn{padding:0 8px}
  .op-header__toggle{width:32px;height:32px;flex-shrink:0;padding:0}
}
@media (max-width:370px){
  .op-header__right .op-btn{display:none}
}

/* Allow long words to shrink on narrow screens. */
.op-band__inner{min-width:0;overflow-wrap:anywhere}
.op-toast{max-width:min(420px,calc(100vw - 48px));overflow-wrap:anywhere}
@media (max-width:640px){
  .op-input,.op-textarea,.op-select{font-size:16px}
}

/* ------------------------------------------------------ forced colors */
/* Decision: under forced colors (a Windows contrast theme) the rules below restore what the design showed
   through a background, a shadow or a transparent border, in the theme's own colours.
   Why: the browser then repaints every background in the page's colour, drops shadows and draws transparent
   borders. Icons are masks painted with their background, so they vanished and icon-only buttons were empty;
   a ticked checkbox looked like an empty one; a field's focus ring and the toast's edge were shadows; every
   menu link carried the current page's underline; the wordmark's i lost its dot.
   Considered: forced-color-adjust:none on the page, which keeps the brand's colours against the theme the
   visitor chose; inline SVG icons, which keep their colour without a rule but change every icon's markup. */
@media (forced-colors:active){
  /* An icon takes the colour the browser gave its parent's text: a link's, a button's or the page's. Where
     preserve-parent-color is not known, it is drawn in the page's text colour. */
  .op-icon,.op-wordmark__i::before{forced-color-adjust:none;background-color:CanvasText}
  @supports (forced-color-adjust:preserve-parent-color){
    .op-icon,.op-wordmark__i::before{forced-color-adjust:preserve-parent-color;background-color:currentColor}
  }

  .op-input:focus,.op-textarea:focus,.op-select:focus{outline:var(--border-focus) solid var(--focus-ring);outline-offset:2px}
  /* The danger colour is gone, so an invalid field is told by its heavier border as well as its message. */
  .op-input--invalid,.op-textarea--invalid,.op-select--invalid{border-width:2px}

  .op-check--on .op-check__box{forced-color-adjust:none;background:Highlight;border-color:Highlight}
  .op-check--on .op-check__mark{background-color:HighlightText}
  .op-radio--on .op-radio__box{forced-color-adjust:none;background:Canvas;border-color:Highlight}

  .op-toast{border:1px solid CanvasText}

  .op-nav-link{border-bottom-color:Canvas}
  .op-nav-link.active{border-bottom-color:LinkText}
}

/* ------------------------------------------------------ framework UI */
h1:focus {
    outline: none;
}

#blazor-error-ui {
    background: var(--surface-raised);
    color: var(--text-heading);
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    /* The room on the right is the close control's: the text ends before it, so a click on the end of a line
       is never the control's. */
    padding: 0.6rem 2.5rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    /* Decision: the rule fits a button as well as the span of Blazor's template, and the mark stays where it was.
       Why: a host that makes the control a button, so the keyboard reaches it and a screen reader names it,
       would otherwise get the browser's button here: a grey box in its own font and colour. The padding makes
       the place to hit 32 by 32 around a mark of 16 by 24, and the offsets are smaller by the padding, so the
       mark has not moved. The focus ring is the stylesheet's own (:focus-visible).
       Considered: leaving the button's look to each host's stylesheet, a second place that styles this one
       control; a larger mark, which changes the bar. */
    #blazor-error-ui .dismiss {
        background: none;
        border: 0;
        color: inherit;
        cursor: pointer;
        font: inherit;
        padding: 4px 8px;
        position: absolute;
        right: 0.25rem;
        top: 0.25rem;
    }

    /* A block, so the line the drawing would stand on adds no height under it. */
    #blazor-error-ui .dismiss svg {
        display: block;
    }
