/* Modernist — design-system tokens and component classes.
 *
 * Ported from the Claude Design project "DepotKontroll UI mockups"
 * (_ds/modernist-5b90eee4-2ef6-41ce-a894-c505c31dc0a5/styles.css). Keep edits in
 * step with that source: it is the system's own reference, and this file is a
 * copy, not a fork.
 *
 * Loaded only at the DepotKontroll origin. The portal and the platform console
 * keep static/css/main.css — a product may carry its own skin, but it does not
 * get to restyle the platform around it. That is also why the product shell
 * (templates/depotkontroll/base_product.html) does not extend base.html: pulling
 * in main.css would put two competing systems on one page.
 *
 * The @import of Archivo present in the source is dropped here. The shell links
 * the font in <head> with preconnect, which starts the download earlier than an
 * @import nested inside a stylesheet can.
 */

:root {
  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201e1d;
  --color-accent: #0083be;
  --color-accent-2: #008e84;
  --color-divider: color-mix(in srgb, #201e1d 40%, transparent);

  /* The logo's own three colours, exactly as drawn. They are a set: the blue
     and the cyan are letterforms sitting on the navy, and they only hold up on
     that ground. #2eb6fe reaches 2.0:1 against --color-bg — unreadable as text
     and barely visible as a border. That is why --color-accent above is the
     same hue seated several steps darker rather than this value: one hue, two
     seats. Reach for these only where the ground is --color-brand-navy. */
  --color-brand-navy: #162c55;
  --color-brand-blue: #2eb6fe;
  --color-brand-cyan: #0af9e9;

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. Re-cut at the
     brand hues by holding each step's lightness, swapping the hue, and scaling
     chroma by the ratio between the new and old base colour. Steps 600 and up
     are the ones with enough contrast to carry text on --color-bg. */
  --color-neutral-100: #f8f4f4;
  --color-neutral-200: #eae7e7;
  --color-neutral-300: #d7d3d3;
  --color-neutral-400: #bab6b6;
  --color-neutral-500: #9b9797;
  --color-neutral-600: #7d7979;
  --color-neutral-700: #605d5d;
  --color-neutral-800: #444141;
  --color-neutral-900: #2d2b2b;

  --color-accent-100: #eff6fb;
  --color-accent-200: #daebf7;
  --color-accent-300: #b8d9f0;
  --color-accent-400: #82c0e9;
  --color-accent-500: #26a3e4;
  --color-accent-600: #0083be;
  --color-accent-700: #006593;
  --color-accent-800: #00486a;
  --color-accent-900: #092f44;

  /* Alarm, kept separate from brand. The old palette had no such role because
     the accent was itself red, so "out of service" could borrow it and still
     read as stop. With a blue accent that borrowing goes silent — a blue
     out-of-service tag is a label, not a warning — so the red survives here on
     its own terms and the two ramps below are the only thing screens should use
     to mean trouble. Danger is the pre-rebrand accent ramp, unchanged. */
  --color-danger: #dd2b0f;
  --color-danger-100: #fff2ef;
  --color-danger-200: #ffe0d9;
  --color-danger-300: #ffc4b8;
  --color-danger-600: #dd2b0f;
  --color-danger-700: #ae1800;
  --color-danger-800: #7c1405;

  --color-warning: #b56200;
  --color-warning-100: #fbf4ef;
  --color-warning-200: #f5e4d8;
  --color-warning-300: #eecdb5;
  --color-warning-600: #b56200;
  --color-warning-700: #8c4a00;
  --color-warning-800: #653300;

  --color-accent-2-100: #ecf8f7;
  --color-accent-2-200: #d1efeb;
  --color-accent-2-300: #a5e2db;
  --color-accent-2-400: #4acfc3;
  --color-accent-2-500: #00b0a4;
  --color-accent-2-600: #008e84;
  --color-accent-2-700: #006d65;
  --color-accent-2-800: #004e48;
  --color-accent-2-900: #003430;

  --font-heading: "Archivo", system-ui, sans-serif;
  --font-heading-weight: 800;
  --font-body: "Archivo", system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;

  --radius-sm: 0px;
  --radius-md: 0px;
  --radius-lg: 0px;

  --shadow-sm: 0 1px 2px color-mix(in srgb, #2d2b2b 14%, transparent);
  --shadow-md: 0 3px 10px color-mix(in srgb, #2d2b2b 16%, transparent);
  --shadow-lg: 0 12px 32px color-mix(in srgb, #2d2b2b 22%, transparent);
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  font-weight: 400;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.12; letter-spacing: -0.015em; margin: 0 0 var(--space-2);
}
h1 { font-size: 42px; }
h2 { font-size: 32px; }
h3 { font-size: 25px; }
h4 { font-size: 20px; }
h5 { font-size: 16px; }
h6 { font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; }

p { margin: 0 0 var(--space-3); }
/* Links take the 700 step rather than --color-accent itself. Running text is
   the one place the accent has to survive at 15px and regular weight, and 700
   clears 4.5:1 on --color-bg where the base accent sits at 3.8:1. Buttons,
   kickers and borders keep the base accent — they are bold, large, or not text
   at all. */
a { color: var(--color-accent-700); text-underline-offset: 3px; }
a:hover { color: var(--color-accent-800); }

/* — brand mark — */
/* The logo is drawn for the navy, so on a light ground it brings the navy with
   it as a tile: the PNG is transparent outside the letterform, and the
   background here shows through it. On a dark ground use .nilsaro-mark--bare,
   which drops the tile and lets the mark sit straight on the surface. */
.nilsaro-mark {
  width: 26px; height: 26px; flex: none;
  background: var(--color-brand-navy);
  padding: 5px 7px; object-fit: contain;
}
.nilsaro-mark--bare { background: none; padding: 0; width: 15px; height: 20px; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
.text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* — rules — */
.hr { height: 2px; border: 0; margin: var(--space-4) 0; background: var(--color-divider); }

/* — buttons — */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.2; color: var(--color-text);
  background: transparent; border: 1px solid transparent;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: var(--radius-md);
}
.btn svg { display: block; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--color-accent); color: var(--color-bg); }
.btn-primary:hover { background: var(--color-accent-600); color: var(--color-bg); }
.btn-primary:active { background: var(--color-accent-700); }
.btn-secondary { border-color: var(--color-divider); }
.btn-secondary:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); color: var(--color-text); }
.btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
.btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
.btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
.btn-danger { color: var(--color-danger-700); border: 1px solid var(--color-danger); }
.btn-danger:hover { background: var(--color-danger-100); color: var(--color-danger-800); }
.btn-icon { width: 36px; height: 36px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); justify-content: flex-start; text-align: left; }

/* — forms — */
.field > label, label.field-label {
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.input, input[type="text"], input[type="search"], input[type="number"],
input[type="email"], input[type="password"], input[type="date"], select, textarea {
  width: 100%; min-height: 36px; padding: 6px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
.input:hover, input:hover, select:hover, textarea:hover {
  border-color: color-mix(in srgb, var(--color-text) 45%, transparent);
}
.input:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  border-color: var(--color-accent); outline-offset: 0;
}
textarea, textarea.input { min-height: 90px; resize: vertical; }
select.input, select { appearance: none; background-image: none; }
input[type="checkbox"], input[type="radio"] { width: auto; min-height: 0; }

.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.radio input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.radio .dot { width: 16px; height: 16px; flex: none; border-radius: 50%; border: 1.5px solid var(--color-divider); }
.radio:hover .dot { border-color: var(--color-accent); }
.radio input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}
.radio input:focus-visible + .dot { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* — cards — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}
.card-kicker { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
.card-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; line-height: 1.2; }
.card-body { margin: 0; font-size: 13px; opacity: 0.8; flex: 1; }
.card-meta { display: flex; align-items: center; gap: 6px; font-size: 11px; color: color-mix(in srgb, var(--color-text) 50%, transparent); }
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — tags — */
/* Every tag carries a hairline, and that is the part doing the work.
 *
 * The fill alone cannot give a tag an edge, because tags appear on three
 * different grounds — a white panel, the #f3f2f2 sidebar, and the #e9e7e6 page
 * — and those three span exactly the range the light ramp steps occupy. Any
 * single tint is invisible against one of them: the 100 step sat within ΔL 1 of
 * the sidebar, and moving to 200 merely swapped which ground it disappeared on,
 * landing within ΔL 0.2 of the page. Measured, not guessed.
 *
 * A border decouples the edge from the ground. At the 300 step the weakest edge
 * against any of the three is ΔL 5.9 — a definite hairline everywhere — while
 * sitting only ΔL 6 from its own fill, so it still reads as a quiet pill rather
 * than a boxed one. The 400 step would be firmer and would look like a button.
 *
 * Padding drops a pixel to pay for the border, so the outer size is unchanged
 * and no row grows when a tag appears in it.
 */
.tag {
  display: inline-flex; align-items: center; font-size: 11px;
  letter-spacing: 0.02em; padding: 2px 9px;
  border: 1px solid transparent;
  border-radius: calc(var(--radius-md) * 0.75);
}
.tag-accent {
  background: var(--color-accent-200); border-color: var(--color-accent-300);
  color: var(--color-accent-800);
}
.tag-accent-2 {
  background: var(--color-accent-2-200); border-color: var(--color-accent-2-300);
  color: var(--color-accent-2-800);
}
.tag-neutral {
  background: var(--color-neutral-200); border-color: var(--color-neutral-300);
  color: var(--color-neutral-800);
}
.tag-outline { border-color: var(--color-accent); color: var(--color-accent); }
/* Use these two, not tag-accent, when the tag reports a problem. The accent
   tags say "this is a kind of thing"; these say "something is wrong". */
.tag-danger {
  background: var(--color-danger-200); border-color: var(--color-danger-300);
  color: var(--color-danger-800);
}
.tag-warning {
  background: var(--color-warning-200); border-color: var(--color-warning-300);
  color: var(--color-warning-800);
}

/* — tables — */
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th {
  text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  padding: var(--space-2); border-bottom: 2px solid var(--color-divider);
}
.table td { padding: var(--space-2); border-bottom: 1px solid var(--color-divider); }
.table tbody tr:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }

/* — dialog — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}
.dialog {
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}
.dialog-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 20px; }
.dialog-body { font-size: 14px; opacity: 0.85; }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }
