/* Stockholm Bakery CRM — quiet dark instrument. See DESIGN.md. */

/* Hanken Grotesk — shared with the stockholm-bakery marketing site for brand
   cohesion. Variable 100–900; digits are tabular by default (all 560 units),
   so money columns align without an OpenType feature. */
@font-face {
  font-family: "Hanken Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/hanken-latin.c501f578bf3f.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Hanken Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/hanken-latin-ext.20672d217485.woff2") format("woff2");
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #0C0F12;
  --surface: #14181D;
  --surface-2: #1B2128;
  --border: #28303A;
  --border-strong: #3A4550;
  --ink: #EAF0F2;
  --ink-soft: #A7B4BD;
  --ink-faint: #6B7883;
  --accent: #0EB9CD;
  --accent-hover: #3DC8D8;
  --accent-ink: #04181B;
  --accent-wash: #0E2A2F;
  --success: #3ECF8E;
  --success-wash: #10241C;
  --warning: #E0B44A;
  --danger: #F0736A;
  --danger-wash: #2A1513;

  --text-2xl: 1.5rem;
  --text-xl: 1.25rem;
  --text-lg: 1.0625rem;
  --text-base: 0.9375rem;
  --text-sm: 0.8125rem;
  --text-xs: 0.6875rem;

  --radius-sm: 8px;
  --radius: 10px;
  --radius-lg: 12px;
  --container: 1040px;
  --shadow-pop: 0 12px 32px -12px rgba(0, 0, 0, .55);

  --z-sticky: 100;
  --z-nav: 200;
  --z-popover: 300;
  --z-modal-backdrop: 400;
  --z-modal: 410;
  --z-toast: 500;

  --font: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

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

/* The [hidden] attribute must win over component display rules (e.g.
   .field { display:flex }), so JS toggling `el.hidden` actually hides. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.2; letter-spacing: -0.01em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
.num { font-variant-numeric: tabular-nums; }

/* ---------- App shell ---------- */

.shell { min-height: 100dvh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: var(--z-nav);
  display: flex; align-items: center; gap: 12px;
  height: 56px; padding: 0 16px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.topbar__brand { display: flex; align-items: center; gap: 10px; font-weight: 600; letter-spacing: -0.01em; }
.topbar__brand .mark {
  width: 26px; height: 26px; border-radius: 7px;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; font-weight: 700; font-size: 14px;
}
.topbar__brand small { display: block; font-size: var(--text-xs); color: var(--ink-faint); font-weight: 500; letter-spacing: 0.02em; }
.topbar__spacer { flex: 1; }

.content { flex: 1; width: 100%; max-width: var(--container); margin: 0 auto; padding: 20px 16px 96px; }

/* Bottom tab bar (mobile) */
.tabbar {
  position: fixed; inset: auto 0 0 0; z-index: var(--z-nav);
  display: flex; background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.tabbar a {
  flex: 1; min-height: 56px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px;
  color: var(--ink-faint); font-size: var(--text-xs); font-weight: 500;
  transition: color .15s var(--ease);
}
.tabbar a svg { width: 22px; height: 22px; }
.tabbar a[aria-current="page"] { color: var(--accent); }
.tabbar a:active { background: var(--surface-2); }

.sidebar { display: none; }

/* ---------- Desktop layout ---------- */
@media (min-width: 900px) {
  .tabbar { display: none; }
  .shell { flex-direction: row; }
  .sidebar {
    display: flex; flex-direction: column; gap: 4px;
    position: sticky; top: 0; align-self: flex-start;
    width: 232px; height: 100dvh; padding: 16px 12px;
    background: var(--surface); border-right: 1px solid var(--border);
    flex-shrink: 0;
  }
  .sidebar__brand { display: flex; align-items: center; gap: 10px; padding: 8px 10px 16px; font-weight: 600; }
  .sidebar__brand .mark { width: 30px; height: 30px; border-radius: 8px; background: var(--accent); color: var(--accent-ink); display: grid; place-items: center; font-weight: 700; }
  .sidebar__brand small { display: block; font-size: var(--text-xs); color: var(--ink-faint); font-weight: 500; }
  .sidebar a.navlink {
    display: flex; align-items: center; gap: 11px;
    padding: 9px 11px; border-radius: var(--radius-sm);
    color: var(--ink-soft); font-size: var(--text-base); font-weight: 500;
    transition: background .15s var(--ease), color .15s var(--ease);
  }
  .sidebar a.navlink svg { width: 19px; height: 19px; opacity: .85; }
  .sidebar a.navlink:hover { background: var(--surface-2); color: var(--ink); }
  .sidebar a.navlink[aria-current="page"] { background: var(--accent-wash); color: var(--accent); }
  .sidebar__foot { margin-top: auto; padding: 8px 10px; border-top: 1px solid var(--border); font-size: var(--text-sm); color: var(--ink-faint); }
  .main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
  .topbar { display: none; }
  .topbar--desk { display: flex; }
  .content { padding: 28px 32px 40px; }
}

/* ---------- Page header ---------- */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; }
.page-head h1 { font-size: var(--text-2xl); }
.page-head .sub { color: var(--ink-soft); font-size: var(--text-sm); margin-top: 2px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 16px; border-radius: var(--radius);
  border: 1px solid transparent; font-size: var(--text-base); font-weight: 600;
  color: var(--ink); background: var(--surface-2); border-color: var(--border);
  transition: background .15s var(--ease), border-color .15s var(--ease), transform .06s var(--ease);
  white-space: nowrap;
}
.btn svg { width: 18px; height: 18px; }
.btn:hover { background: color-mix(in srgb, var(--surface-2) 70%, var(--ink) 6%); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn--primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.btn--primary:hover { background: var(--accent-hover); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--ink-soft); }
.btn--ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn--danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn--danger:hover { background: var(--danger-wash); }
.btn--sm { min-height: 36px; padding: 0 12px; font-size: var(--text-sm); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--block { width: 100%; }

/* ---------- Cards / panels ---------- */
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.panel__head { padding: 14px 16px; border-bottom: 1px solid var(--border); font-weight: 600; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.panel__body { padding: 16px; }
.stack { display: flex; flex-direction: column; }
.stack > * + * { margin-top: var(--gap, 16px); }

/* ---------- Forms ---------- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { font-size: var(--text-sm); font-weight: 500; color: var(--ink-soft); }
.field .hint { font-size: var(--text-xs); color: var(--ink-faint); }
.field .err { font-size: var(--text-xs); color: var(--danger); }
.input, .select, .textarea {
  width: 100%; min-height: 44px; padding: 10px 12px;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--radius);
  font: inherit; transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.textarea { min-height: 88px; resize: vertical; line-height: 1.5; }
.input::placeholder, .textarea::placeholder { color: var(--ink-faint); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--border-strong);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 24%, transparent);
}
.input--money { text-align: right; font-variant-numeric: tabular-nums; }
.input--invalid { border-color: var(--danger); }
.form-grid { display: grid; gap: 16px; }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 860px) { .form-grid--3 { grid-template-columns: 1fr 1fr 1fr; } }
.form-actions { display: flex; gap: 10px; margin-top: 4px; }

/* ---------- Trilingual content rows ---------- */
/* One concept per row (headline, lead, …), its ES/EN/SV inputs side by side.
   Below 860px they stack, each still tagged with its language. */
.lang-row + .lang-row { margin-top: 18px; }
.lang-row__label { font-size: var(--text-sm); font-weight: 600; margin-bottom: 8px; }
.lang-row__tag {
  display: block; font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.06em; color: var(--ink-faint); margin-bottom: 4px;
}

/* ---------- Status chips ---------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px;
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.02em;
}
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.chip--draft { color: var(--ink-soft); background: var(--surface-2); }
.chip--sent { color: var(--accent); background: var(--accent-wash); }
.chip--paid { color: var(--success); background: var(--success-wash); }

/* ---------- Lists / rows (mobile) ---------- */
.rows { display: flex; flex-direction: column; }
.row-link {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 4px; border-bottom: 1px solid var(--border);
  transition: background .12s var(--ease);
}
.row-link:active { background: var(--surface-2); }
.row-link__main { min-width: 0; flex: 1; }
.row-link__title { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-link__meta { font-size: var(--text-sm); color: var(--ink-soft); margin-top: 2px; }
.row-link__amount { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.row-link__amount .chip { margin-top: 4px; }

/* ---------- Data table (desktop) ---------- */
/* Hidden below 720px, where `.rows` cards take over — but `overflow-x` lives
   here rather than in the media query below, because the invoice and order
   detail pages force this visible on mobile with an inline `display:block`
   (they have no card variant). Without a scroll container at that width the
   wide table pushes the whole page sideways instead of scrolling itself. */
.table-wrap { display: none; overflow-x: auto; }
@media (min-width: 720px) {
  .rows { display: none; }
  /* ...except lists that have no desktop table to switch to. `.rows` is the
     mobile half of a two-presentation pattern: hidden here so `.table-wrap`
     can take over. A page that renders `.rows` WITHOUT a matching table
     therefore renders nothing at all above 720px — which is what happened to
     the shop hub, the category list and the content list: their markup was
     correct and completely invisible on every desktop browser.
     These lists are short and navigational, so the card presentation is the
     right one at every width. Specificity (0,2,0) beats the rule above without
     needing !important. `shop/tests_templates.py` enforces the pairing. */
  .rows--nav { display: flex; }
  .table-wrap { display: block; overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); }
  table.data { width: 100%; border-collapse: collapse; font-size: var(--text-base); }
  table.data th, table.data td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--border); }
  table.data thead th { position: sticky; top: 0; background: var(--surface); font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft); }
  table.data tbody tr { transition: background .12s var(--ease); }
  table.data tbody tr:hover { background: var(--surface-2); }
  table.data tbody tr:last-child td { border-bottom: none; }
  table.data .r { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
  table.data tr.clickable { cursor: pointer; }
}

/* ---------- Stat tiles (dashboard) ---------- */
.tiles { display: grid; gap: 12px; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 720px) { .tiles { grid-template-columns: repeat(4, 1fr); } }
.tile { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px; }
.tile .k { font-size: var(--text-sm); color: var(--ink-soft); font-weight: 500; }
.tile .v { font-size: var(--text-xl); font-weight: 600; margin-top: 6px; font-variant-numeric: tabular-nums; }
.tile .v.accent { color: var(--accent); }

/* ---------- Empty state ---------- */
.empty { text-align: center; padding: 48px 20px; color: var(--ink-soft); }
.empty svg { width: 40px; height: 40px; color: var(--ink-faint); margin-bottom: 12px; }
.empty h3 { font-size: var(--text-lg); color: var(--ink); margin-bottom: 6px; }
.empty p { font-size: var(--text-sm); margin-bottom: 18px; }

/* ---------- Language switcher ---------- */
.langswitch { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.langswitch button {
  padding: 6px 12px; min-height: 36px; background: transparent; border: none;
  color: var(--ink-faint); font-size: var(--text-sm); font-weight: 600;
}
.langswitch button[aria-current="true"] { background: var(--surface-2); color: var(--accent); }

/* ---------- Login ---------- */
.login-wrap { min-height: 100dvh; display: grid; place-items: center; padding: 24px; }
.login-card { width: 100%; max-width: 380px; }
.login-card .brand { display: flex; align-items: center; gap: 12px; justify-content: center; margin-bottom: 24px; }
.login-card .brand .mark { width: 40px; height: 40px; border-radius: 10px; background: var(--accent); color: var(--accent-ink); display: grid; place-items: center; font-weight: 700; font-size: 20px; }

/* ---------- Messages ---------- */
.messages { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.msg { padding: 12px 14px; border-radius: var(--radius); font-size: var(--text-sm); border: 1px solid var(--border); background: var(--surface); }
.msg--success { border-color: color-mix(in srgb, var(--success) 40%, var(--border)); background: var(--success-wash); color: var(--success); }
.msg--error { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); background: var(--danger-wash); color: var(--danger); }

/* ---------- Utilities ---------- */
/* ---------- Invoice builder ---------- */
.builder__grid { display: grid; gap: 16px; }
@media (min-width: 960px) { .builder__grid { grid-template-columns: 1fr 300px; align-items: start; } }

.line { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; margin-bottom: 12px; background: var(--surface-2); }
.line[hidden] { display: none; }
.line__top { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 10px; }
.line__top .field { flex: 1; }
.line__remove { flex-shrink: 0; min-height: 44px; min-width: 44px; padding: 0; }
.line .field { margin-bottom: 10px; }
.line__nums { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 0; }
@media (min-width: 560px) { .line__nums { grid-template-columns: repeat(4, 1fr); } }
.line__nums .field { margin-bottom: 0; }
.line__total {
  display: flex; align-items: center; justify-content: flex-end;
  min-height: 44px; padding: 10px 12px; font-weight: 600;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  font-variant-numeric: tabular-nums;
}

.totals { padding: 16px; display: flex; flex-direction: column; gap: 2px; }
.totals__row { display: flex; justify-content: space-between; align-items: baseline; padding: 6px 0; color: var(--ink-soft); }
.totals__row > span:last-child { color: var(--ink); font-variant-numeric: tabular-nums; }
.totals__grand { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 12px; font-size: var(--text-xl); }
.totals__grand > span:first-child { color: var(--ink); font-weight: 700; }
.totals__grand > span:last-child { color: var(--accent); font-weight: 700; }
.totals--flat { border-top: 1px solid var(--border); }

@media (max-width: 959px) {
  .builder__rail { position: sticky; bottom: calc(56px + env(safe-area-inset-bottom, 0px)); z-index: var(--z-sticky); }
  .builder__rail .totals { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-pop); }
}
@media (min-width: 960px) { .builder__rail .totals { position: sticky; top: 24px; } }

@keyframes tick { from { opacity: .35; } to { opacity: 1; } }
.tick { animation: tick .18s var(--ease); }

/* Inline "new client" — a link-style toggle + a bordered-top inset form,
   kept at the same altitude as the other fields (not a nested card). */
.linkish {
  align-self: flex-start; background: none; border: none; padding: 4px 0;
  color: var(--accent); font-size: var(--text-sm); font-weight: 600; cursor: pointer;
}
.linkish:hover { color: var(--accent-hover); }
.linkish:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.new-client { gap: 12px; border-top: 1px solid var(--border); padding-top: 16px; margin-top: 4px; }
.new-client__head { font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft); }
.new-client .err[hidden] { display: none; }

/* ---------- Daily availability ----------
   A morning screen, used one-handed on a phone: the day stepper and every
   row's control are full touch targets, and the row is a single line so the
   whole day's list fits on one screen. */
.daybar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.daybar .input { flex: 1; min-width: 0; }
.daybar__step { min-width: 48px; font-size: var(--text-lg); line-height: 1; }
.daybar__label {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--text-sm); color: var(--ink-soft); margin-bottom: 16px;
}

.avail {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px;
}
.avail__main { flex: 1; min-width: 0; }
.avail__title { font-weight: 500; }
.avail__meta { font-size: var(--text-sm); color: var(--ink-soft); margin-top: 2px; }
.avail__control { display: flex; align-items: center; gap: 8px; }
.avail__unit { font-size: var(--text-sm); color: var(--ink-soft); }
/* Marks a row that was filled in from the variant's standing daily default,
   so a pre-filled number never looks like something the owner forgot doing. */
.avail__default { color: var(--accent); font-weight: 500; }
.avail__switch { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.input--qty { width: 88px; text-align: center; font-variant-numeric: tabular-nums; }
.avail__err { flex-basis: 100%; font-size: var(--text-xs); color: var(--danger); }

input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--accent); }

.only-desk { display: none; }
@media (min-width: 900px) { .only-desk { display: inline-flex; } }
.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.flex { display: flex; }
.between { justify-content: space-between; }
.center { align-items: center; }
.gap-8 { gap: 8px; } .gap-12 { gap: 12px; }
.mt-8 { margin-top: 8px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.wrap-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
