/* ==========================================================================
   iStockPro — KRYPTON UI KIT
   --------------------------------------------------------------------------
   Hand-written plain CSS. It is NOT compiled from Tailwind, so you can edit
   it directly on the server and see the change immediately — no Node, no
   build step. Loaded AFTER app.css by both the public header and the admin
   shell.

   Everything here reproduces the Krypton Toolkit look of the desktop app:
   bevelled chrome, pale-blue caption gradients, sunken fields, and modal
   dialogs that read like real Windows dialogs.

   Class prefix is kr- and every name added here is new, so nothing that
   app.css already ships is overwritten.
   ========================================================================== */

:root {
  --kr-chrome:      #CBDDF0;
  --kr-chrome-dim:  #A9C6E3;
  --kr-chrome-lit:  #E8F1FA;
  --kr-ribbon:      #EEF5FC;
  --kr-ribbon-dim:  #DAE7F4;
  --kr-cap-from:    #E4EEFA;
  --kr-cap-to:      #CFE0F3;
  --kr-cap-text:    #1F3864;
  --kr-cap-border:  #A8C2DE;
  --kr-grid-head:   #EEF2F7;
  --kr-select:      #FFE9A8;
  --kr-border:      #9BB8D5;
  --kr-border-soft: #C3D6E8;
  --kr-panel:       #FBFDFF;
  --kr-status:      #E4EEF8;
  --kr-field:       #FFFFFF;
  --kr-danger:      #C00000;
  --kr-ok:          #047857;
  --kr-warn:        #B45309;
  --kr-primary:     #1E3A5F;
  --kr-primary-600: #2A5183;
  --kr-accent:      #059669;
  --kr-radius:      4px;

  /* ------------------------------------------------------------------
     ModDialogStyle — the exact palette the desktop dialogs are painted
     with (ModDialogStyle.vb). Taken value for value so the site and the
     software cannot drift apart: change it there, change it here.

       CBleu       Color.FromArgb(21, 101, 192)
       CBleuFonce  Color.FromArgb(16,  78, 148)
       pressed     Color.FromArgb(12,  62, 118)
       CBandeau    Color.FromArgb(242,246, 252)
       CTrait      Color.FromArgb(214,224, 236)
       CGris       Color.FromArgb(110,124, 145)
       CTexte      Color.FromArgb(28,  40,  58)
     ------------------------------------------------------------------ */
  --md-bleu:       #1565C0;
  --md-bleu-fonce: #104E94;
  --md-bleu-press: #0C3E76;
  --md-bandeau:    #F2F6FC;
  --md-trait:      #D6E0EC;
  --md-gris:       #6E7C91;
  --md-texte:      #1C283A;
}

/* ============================================================ PANEL / GROUP */

/* A KryptonHeaderGroup: caption bar + body. The workhorse container. */
.kr-panel {
  border: 1px solid var(--kr-border);
  border-radius: var(--kr-radius);
  background: var(--kr-panel);
  box-shadow: 0 1px 2px rgba(15, 30, 49, .07), inset 0 1px 0 rgba(255, 255, 255, .8);
  overflow: hidden;
}

.kr-panel-cap {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .75rem;
  border-bottom: 1px solid var(--kr-cap-border);
  background-image: linear-gradient(to bottom, var(--kr-cap-from) 0%, var(--kr-cap-to) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .65);
  font-size: 12px;
  font-weight: 700;
  color: var(--kr-cap-text);
  line-height: 1.4;
}

.kr-panel-cap .kr-cap-note {
  margin-inline-start: auto;
  font-weight: 600;
  font-size: 11px;
  color: var(--kr-primary-600);
}

.kr-panel-cap svg { width: 14px; height: 14px; flex: none; }

.kr-panel-body { padding: 1rem; }

/* A pale strip for hints and legends inside a panel. */
.kr-note {
  border: 1px solid var(--kr-border-soft);
  border-radius: var(--kr-radius);
  background: var(--kr-ribbon);
  padding: .6rem .75rem;
  font-size: 12px;
  line-height: 1.6;
  color: var(--kr-cap-text);
}
.kr-note strong { font-weight: 700; }
.kr-note code {
  background: #fff;
  border: 1px solid var(--kr-border-soft);
  border-radius: 3px;
  padding: 0 .25rem;
  font-size: 11px;
}

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

.kr-label {
  display: block;
  margin-bottom: .3rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--kr-cap-text);
}

.kr-input,
.kr-select,
.kr-textarea {
  width: 100%;
  border: 1px solid var(--kr-border);
  border-radius: 3px;
  background: var(--kr-field);
  padding: .45rem .6rem;
  font-size: 13px;
  color: #0F172A;
  box-shadow: inset 0 1px 2px rgba(30, 58, 95, .10);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.kr-textarea { line-height: 1.6; resize: vertical; }

.kr-input:focus,
.kr-select:focus,
.kr-textarea:focus {
  outline: none;
  border-color: var(--kr-primary-600);
  box-shadow: inset 0 1px 2px rgba(30, 58, 95, .10), 0 0 0 3px rgba(42, 81, 131, .18);
}

.kr-input:disabled,
.kr-select:disabled,
.kr-textarea:disabled { background: #F1F5F9; color: #64748B; }

.kr-input.is-invalid { border-color: var(--kr-danger); }
.kr-input.is-valid   { border-color: var(--kr-ok); }

.kr-hint  { margin-top: .3rem; font-size: 11.5px; color: #64748B; line-height: 1.5; }
.kr-error { margin-top: .3rem; font-size: 11.5px; color: var(--kr-danger); font-weight: 600; }

/* Checkbox row that reads like a desktop option. */
.kr-check {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  padding: .5rem .6rem;
  border: 1px solid var(--kr-border-soft);
  border-radius: 3px;
  background: #fff;
  cursor: pointer;
  font-size: 13px;
  color: #0F172A;
}
.kr-check:hover { border-color: var(--kr-border); background: var(--kr-ribbon); }
.kr-check input { margin-top: .15rem; accent-color: var(--kr-primary-600); flex: none; }
.kr-check span small { display: block; color: #64748B; font-size: 11.5px; line-height: 1.5; }

/* Two-column form grid used all over the settings pages. */
.kr-grid { display: grid; gap: .9rem; }
@media (min-width: 640px) { .kr-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 640px) { .kr-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.kr-span-2 { grid-column: 1 / -1; }

/* ================================================================== BUTTONS */

.kr-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  border: 1px solid var(--kr-border-soft);
  border-radius: 3px;
  padding: .45rem .9rem;
  font-size: 12px;
  font-weight: 700;
  color: var(--kr-primary);
  cursor: pointer;
  white-space: nowrap;
  background-image: linear-gradient(to bottom, #FFFFFF 0%, #E8F1FA 100%);
  box-shadow: 0 1px 1px rgba(15, 30, 49, .08);
  transition: background-image .15s ease, border-color .15s ease, transform .08s ease;
}
.kr-button:hover  { border-color: var(--kr-border); background-image: linear-gradient(to bottom, #FFFFFF 0%, #D6E7F7 100%); }
.kr-button:active { transform: translateY(1px); }
.kr-button svg { width: 14px; height: 14px; flex: none; }
.kr-button:disabled { opacity: .55; cursor: not-allowed; transform: none; }

.kr-button-primary {
  border-color: #14532D;
  color: #fff;
  background-image: linear-gradient(to bottom, #10B981 0%, var(--kr-accent) 55%, #047857 100%);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .18);
}
.kr-button-primary:hover { background-image: linear-gradient(to bottom, #34D399 0%, #059669 55%, #047857 100%); }

.kr-button-navy {
  border-color: #0F1E31;
  color: #fff;
  background-image: linear-gradient(to bottom, var(--kr-primary-600) 0%, var(--kr-primary) 100%);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .22);
}
.kr-button-navy:hover { background-image: linear-gradient(to bottom, #33619B 0%, #24466F 100%); }

.kr-button-danger {
  border-color: #7F1D1D;
  color: #fff;
  background-image: linear-gradient(to bottom, #EF4444 0%, var(--kr-danger) 100%);
  text-shadow: 0 1px 0 rgba(0, 0, 0, .2);
}
.kr-button-danger:hover { background-image: linear-gradient(to bottom, #F87171 0%, #A81010 100%); }

.kr-button-sm { padding: .3rem .6rem; font-size: 11px; }

/* ================================================================ TAB STRIP */

/* Ribbon-style tab strip. Anchor tags, so it works with ?tab= links. */
.kr-tabstrip {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 2px;
  padding: .35rem .5rem 0;
  border: 1px solid var(--kr-border);
  border-radius: var(--kr-radius) var(--kr-radius) 0 0;
  border-bottom-color: var(--kr-border);
  background-image: linear-gradient(to bottom, var(--kr-ribbon) 0%, var(--kr-ribbon-dim) 100%);
}

.kr-tabstrip a {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  padding: .4rem .8rem;
  font-size: 12px;
  font-weight: 700;
  color: var(--kr-primary-600);
  text-decoration: none;
  transition: background .15s ease, border-color .15s ease;
}
.kr-tabstrip a:hover { border-color: var(--kr-border-soft); background: rgba(255, 255, 255, .7); }

.kr-tabstrip a.is-active {
  margin-bottom: -1px;
  border-color: var(--kr-border);
  background: #fff;
  color: var(--kr-primary);
  padding-bottom: calc(.4rem + 1px);
}

/* The body that sits directly under a tab strip. */
.kr-tabbody {
  border: 1px solid var(--kr-border);
  border-top: none;
  border-radius: 0 0 var(--kr-radius) var(--kr-radius);
  background: #fff;
  padding: 1.25rem;
}

/* ================================================================ STATUS BAR */

.kr-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  border-top: 1px solid var(--kr-border);
  background: var(--kr-status);
  padding: .4rem .75rem;
  font-size: 11px;
  color: var(--kr-primary-600);
}
.kr-status .kr-sep { width: 1px; align-self: stretch; background: var(--kr-border-soft); }

/* ==================================================================== PILLS */

.kr-pill {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  border: 1px solid var(--kr-border-soft);
  border-radius: 999px;
  padding: .1rem .55rem;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  background: #fff;
  color: var(--kr-primary-600);
}
.kr-pill::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 999px;
  background: currentColor;
}
.kr-pill-on   { color: var(--kr-ok);     border-color: #A7F3D0; background: #ECFDF5; }
.kr-pill-off  { color: #64748B;          border-color: #E2E8F0; background: #F8FAFC; }
.kr-pill-warn { color: var(--kr-warn);   border-color: #FDE68A; background: #FFFBEB; }
.kr-pill-bad  { color: var(--kr-danger); border-color: #FECACA; background: #FEF2F2; }

/* An explicit display on a class beats the browser's own [hidden] rule, so a
   pill marked hidden would otherwise stay on screen. Restore it. */
.kr-pill[hidden] { display: none; }

/* =================================================================== DIALOG */

/* Modal dialog with a real Krypton caption bar and a bevelled button row.
   Markup: see pages/partials/kr-dialog.php — driven by assets/js/krypton.js. */
.kr-dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(15, 30, 49, .45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .18s ease, visibility .18s ease;
}
.kr-dialog-backdrop.is-open { opacity: 1; visibility: visible; }

.kr-dialog {
  width: 100%;
  max-width: 30rem;
  max-height: calc(100vh - 2rem);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--kr-border);
  border-radius: 6px;
  background: var(--kr-panel);
  box-shadow: 0 2px 4px rgba(15, 30, 49, .10),
              0 12px 32px rgba(15, 30, 49, .28),
              0 32px 64px rgba(15, 30, 49, .18);
  transform: translateY(-10px) scale(.98);
  transition: transform .18s cubic-bezier(.22, 1, .36, 1);
  overflow: hidden;
}
.kr-dialog-backdrop.is-open .kr-dialog { transform: none; }

.kr-dialog-wide { max-width: 46rem; }

/* Caption bar — the light-to-dark blue gradient of the app's title bar. */
.kr-dialog-cap {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .5rem .5rem .8rem;
  border-bottom: 1px solid var(--kr-border);
  background-image: linear-gradient(to bottom, var(--kr-chrome-lit) 0%, var(--kr-chrome) 45%, var(--kr-chrome-dim) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .85);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--kr-cap-text);
  cursor: default;
  user-select: none;
}
.kr-dialog-cap .kr-dialog-icon { width: 16px; height: 16px; flex: none; }
.kr-dialog-cap .kr-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The caption close box, drawn like the app's own. */
.kr-dialog-x {
  width: 22px; height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-border-soft);
  border-radius: 3px;
  background-image: linear-gradient(to bottom, #FFFFFF 0%, #E8F1FA 100%);
  color: var(--kr-primary);
  cursor: pointer;
  flex: none;
}
.kr-dialog-x:hover { border-color: #7F1D1D; color: #fff; background-image: linear-gradient(to bottom, #EF4444 0%, var(--kr-danger) 100%); }
.kr-dialog-x svg { width: 11px; height: 11px; }

.kr-dialog-body {
  padding: 1.1rem 1.1rem 1.2rem;
  overflow-y: auto;
  font-size: 13.5px;
  line-height: 1.65;
  color: #0F172A;
  background: #fff;
}
.kr-dialog-body p { margin: 0 0 .7rem; }
.kr-dialog-body p:last-child { margin-bottom: 0; }

/* Icon + message layout for confirm / alert dialogs. */
.kr-dialog-msg { display: flex; gap: .9rem; align-items: flex-start; }
.kr-dialog-msg .kr-dialog-glyph {
  width: 40px; height: 40px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--kr-border-soft);
  background: var(--kr-ribbon);
  color: var(--kr-primary-600);
}
.kr-dialog-msg .kr-dialog-glyph svg { width: 20px; height: 20px; }
.kr-dialog-msg.is-ok   .kr-dialog-glyph { border-color: #A7F3D0; background: #ECFDF5; color: var(--kr-ok); }
.kr-dialog-msg.is-warn .kr-dialog-glyph { border-color: #FDE68A; background: #FFFBEB; color: var(--kr-warn); }
.kr-dialog-msg.is-bad  .kr-dialog-glyph { border-color: #FECACA; background: #FEF2F2; color: var(--kr-danger); }
.kr-dialog-msg h3 { margin: 0 0 .3rem; font-size: 14.5px; font-weight: 700; color: var(--kr-cap-text); }

/* Button row, right-aligned like every Windows dialog. */
.kr-dialog-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: .5rem;
  padding: .7rem .9rem;
  border-top: 1px solid var(--kr-border);
  background-image: linear-gradient(to bottom, #F6FAFE 0%, var(--kr-status) 100%);
}
.kr-dialog-foot .kr-dialog-foot-start { margin-inline-end: auto; font-size: 11.5px; color: var(--kr-primary-600); }

body.kr-dialog-open { overflow: hidden; }

/* ================================================================== TABLES */

.kr-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.kr-table thead th {
  text-align: start;
  padding: .45rem .65rem;
  border-bottom: 1px solid var(--kr-border);
  background: var(--kr-grid-head);
  font-size: 11px;
  font-weight: 700;
  color: var(--kr-cap-text);
  white-space: nowrap;
}
.kr-table tbody td { padding: .5rem .65rem; border-bottom: 1px solid #EEF2F7; vertical-align: top; }
.kr-table tbody tr:hover { background: #F8FBFF; }
.kr-table tbody tr.is-selected { background: var(--kr-select); }
.kr-table-wrap { overflow-x: auto; border-radius: 0 0 var(--kr-radius) var(--kr-radius); }

/* ============================================================ INLINE STATES */

/* Live phone-check feedback under the order form's phone box. */
.kr-check-line {
  display: none;
  align-items: center;
  gap: .4rem;
  margin-top: .4rem;
  font-size: 12px;
  font-weight: 600;
}
.kr-check-line.is-shown { display: flex; }
.kr-check-line.is-ok   { color: var(--kr-ok); }
.kr-check-line.is-bad  { color: var(--kr-danger); }
.kr-check-line.is-busy { color: var(--kr-primary-600); }
.kr-check-line svg { width: 14px; height: 14px; flex: none; }

.kr-spin { animation: kr-spin 0.9s linear infinite; }
@keyframes kr-spin { to { transform: rotate(360deg); } }

/* RTL: the caption close box and footer buttons mirror automatically because
   they use logical properties, but the gradient direction stays vertical. */
[dir="rtl"] .kr-dialog-cap { padding: .5rem .8rem .5rem .5rem; }

/* ============================================================ FEATURE CARD */

/* The grid of capability cards on the home and features pages. A kr-panel
   with the icon given its own sunken well, so the caption reads like a real
   header group rather than a web card with a tick in it. */
.kr-feature {
  display: flex;
  flex-direction: column;
  transition: transform .25s cubic-bezier(.22, 1, .36, 1), box-shadow .25s ease, border-color .25s ease;
}
.kr-feature:hover {
  transform: translateY(-2px);
  border-color: var(--kr-primary-600);
  box-shadow: 0 2px 4px rgba(15, 30, 49, .10), 0 12px 28px rgba(15, 30, 49, .14);
}

.kr-feature .kr-panel-cap {
  gap: .55rem;
  padding: .5rem .6rem;
  font-size: 12.5px;
  line-height: 1.35;
}

/* The icon sits in a recessed square, like a toolbar glyph. */
.kr-feature-icon {
  width: 24px;
  height: 24px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-cap-border);
  border-radius: 3px;
  background-image: linear-gradient(to bottom, #FFFFFF 0%, #DCE9F7 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9);
  color: var(--kr-primary-600);
}
.kr-feature-icon svg { width: 13px; height: 13px; }
.kr-feature:hover .kr-feature-icon { color: var(--kr-accent); border-color: var(--kr-accent); }

.kr-feature .kr-panel-body { flex: 1; padding: .8rem .85rem .9rem; }

.kr-feature-body {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.65;
  color: #475569;
}

/* The caption text must never be clipped mid-word on a narrow phone. */
@media (max-width: 480px) {
  .kr-feature .kr-panel-cap .truncate { white-space: normal; overflow: visible; }
}

/* ==================================================================== BRAND */

.kr-brand {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  flex-shrink: 0;
  text-decoration: none;
  min-width: 0;
}

/* An uploaded logo. Height is set inline from the dashboard; width follows. */
.kr-brand-logo {
  display: block;
  width: auto;
  max-width: 220px;
  object-fit: contain;
}

/* The fallback mark, used when no logo has been uploaded. */
.kr-brand-mark {
  width: 36px;
  height: 36px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-border);
  border-radius: 5px;
  background-image: linear-gradient(to bottom, var(--kr-primary-600) 0%, var(--kr-primary) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 1px 2px rgba(15, 30, 49, .18);
  color: #fff;
}
.kr-brand-mark svg { width: 19px; height: 19px; }
.kr-brand-mark-sm { width: 28px; height: 28px; border-radius: 4px; }
.kr-brand-mark-sm svg { width: 15px; height: 15px; }

.kr-brand-name {
  font-family: Rubik, 'Nunito Sans', system-ui, sans-serif;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--kr-primary);
  white-space: nowrap;
}
.kr-brand-admin .kr-brand-name { font-size: 15px; }

/* The tagline. Hidden on narrow screens — it is supporting text, not a label. */
.kr-brand-tagline {
  display: none;
  padding-inline-start: .7rem;
  margin-inline-start: .1rem;
  border-inline-start: 1px solid var(--kr-border-soft);
  font-size: 11.5px;
  line-height: 1.35;
  font-weight: 600;
  color: var(--kr-primary-600);
  /* One line, clipped. A tagline that wraps to two lines in the header makes
     the whole bar look accidental. */
  max-width: 17rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (min-width: 1180px) { .kr-brand-tagline { display: block; } }

.kr-brand-footer { margin-bottom: .2rem; }

/* ============================================================= PUBLIC FORMS */

/* A public form presented as a real dialog: caption bar, client area, and a
   command row at the bottom. This is what makes the order and trial pages
   read as part of the software rather than as a generic web form. */
.kr-form-window {
  border: 1px solid var(--kr-border);
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 2px 4px rgba(15, 30, 49, .08),
              0 12px 32px rgba(15, 30, 49, .10);
  overflow: hidden;
}

.kr-form-cap {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .6rem .85rem;
  border-bottom: 1px solid var(--kr-border);
  background-image: linear-gradient(to bottom, var(--kr-chrome-lit) 0%, var(--kr-chrome) 45%, var(--kr-chrome-dim) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .85);
  font-size: 13px;
  font-weight: 700;
  color: var(--kr-cap-text);
}
.kr-form-cap svg { width: 15px; height: 15px; flex: none; }
.kr-form-cap .kr-form-step {
  margin-inline-start: auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--kr-primary-600);
  white-space: nowrap;
}

.kr-form-body { padding: 1.3rem 1.2rem 1.4rem; }

/* The command row — where a desktop dialog puts OK and Cancel. */
.kr-form-foot {
  padding: .9rem 1.2rem 1.1rem;
  border-top: 1px solid var(--kr-border-soft);
  background-image: linear-gradient(to bottom, #F7FBFF 0%, var(--kr-status) 100%);
}

/* Public form controls, matching the dashboard's. */
.kr-form-window label.kr-pub-label {
  display: block;
  margin-bottom: .35rem;
  font-size: 12px;
  font-weight: 700;
  color: var(--kr-cap-text);
}
.kr-form-window label.kr-pub-label .kr-opt {
  font-weight: 500;
  color: #94A3B8;
}

.kr-pub-field {
  width: 100%;
  border: 1px solid var(--kr-border);
  border-radius: 3px;
  background: #fff;
  padding: .6rem .7rem;
  font-size: 14px;
  color: #0F172A;
  box-shadow: inset 0 1px 2px rgba(30, 58, 95, .09);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.kr-pub-field:focus {
  outline: none;
  border-color: var(--kr-primary-600);
  box-shadow: inset 0 1px 2px rgba(30, 58, 95, .09), 0 0 0 3px rgba(42, 81, 131, .16);
}
.kr-pub-field.is-error { border-color: var(--kr-danger); background: #FFFBFB; }
textarea.kr-pub-field { line-height: 1.6; resize: vertical; }

/* The primary action, bevelled like the app's default button. */
.kr-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  width: 100%;
  border: 1px solid #14532D;
  border-radius: 4px;
  padding: .8rem 1.4rem;
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  cursor: pointer;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .18);
  background-image: linear-gradient(to bottom, #10B981 0%, var(--kr-accent) 55%, #047857 100%);
  box-shadow: 0 1px 2px rgba(15, 30, 49, .18), inset 0 1px 0 rgba(255, 255, 255, .22);
  transition: filter .15s ease, transform .08s ease;
}
.kr-submit:hover  { filter: brightness(1.07); }
.kr-submit:active { transform: translateY(1px); }
.kr-submit:disabled { opacity: .6; cursor: not-allowed; transform: none; }

/* ============================================================ SITE HEADER */

/* A thin chrome rail above the navigation, the way an application window
   carries a caption above its menu bar. */
.kr-topbar {
  border-bottom: 1px solid var(--kr-border);
  background-image: linear-gradient(to bottom, var(--kr-chrome-lit) 0%, var(--kr-chrome) 55%, var(--kr-chrome-dim) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8);
  font-size: 11.5px;
  color: var(--kr-cap-text);
}
.kr-topbar-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .3rem 1.25rem;
  min-height: 26px;
}
.kr-topbar a { color: var(--kr-cap-text); text-decoration: none; font-weight: 600; }
.kr-topbar a:hover { text-decoration: underline; }
.kr-topbar .kr-topbar-end { margin-inline-start: auto; display: flex; align-items: center; gap: .9rem; }
@media (max-width: 640px) { .kr-topbar-hide-sm { display: none; } }

/* =============================================================== QUOTE BUILDER */

/* One selectable option: the control on the left, its price on the right. */
.kr-opt {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
}
.kr-opt > .kr-check,
.kr-opt > label.kr-check { flex: 1; min-width: 0; }

.kr-opt-price {
  flex: none;
  min-width: 6.5rem;
  padding-top: .55rem;
  text-align: end;
  font-size: 13px;
  font-weight: 700;
  color: var(--kr-primary);
  direction: ltr;
}
.kr-opt-price .kr-pill { font-size: 9.5px; }

/* An option the chosen licence already covers: visibly settled, not disabled
   into invisibility — the customer should see what they are getting. */
.kr-opt.is-included > .kr-check {
  border-color: #A7F3D0;
  background: #F0FDF7;
}
.kr-opt.is-included .kr-opt-price > [data-kr-opt-amount] { display: none; }
.kr-opt.is-included input[type="checkbox"],
.kr-opt.is-included input[type="number"] { pointer-events: none; opacity: .55; }

/* The running summary. */
.kr-quote-lines {
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 22rem;
  overflow-y: auto;
}
.kr-quote-lines li {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  padding: .35rem 0;
  border-bottom: 1px dashed #E2E8F0;
  font-size: 12.5px;
  color: #334155;
}
.kr-quote-lines li:last-child { border-bottom: 0; }
.kr-quote-lines li span:first-child { flex: 1; min-width: 0; }
.kr-quote-lines li .kr-line-amt {
  flex: none;
  font-weight: 700;
  color: var(--kr-primary);
  direction: ltr;
  white-space: nowrap;
}
.kr-quote-lines li.is-included .kr-line-amt { color: var(--kr-ok); font-weight: 600; }
.kr-quote-lines .kr-line-empty { color: #94A3B8; font-style: italic; border: 0; }

.kr-quote-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: .8rem 1rem;
  border-top: 1px solid var(--kr-border);
  border-bottom: 1px solid var(--kr-border-soft);
  background: var(--kr-status);
  font-size: 13px;
  font-weight: 700;
  color: var(--kr-cap-text);
}
.kr-quote-total strong {
  font-family: Rubik, 'Nunito Sans', system-ui, sans-serif;
  font-size: 25px;
  letter-spacing: -.02em;
  color: var(--kr-primary);
}

/* ================================================================ SPOTLIGHT */

.kr-spotlight { display: flex; flex-direction: column; }
.kr-spotlight .kr-form-body { flex: 1; }

.kr-spotlight-lead {
  margin: 0 0 1rem;
  font-size: 14.5px;
  line-height: 1.7;
  color: #334155;
}

/* A numbered sequence, because these two features are a sequence — the value
   is in the order of the steps, not in a list of nouns. */
.kr-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: krstep;
}
.kr-steps li {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .55rem 0;
  border-top: 1px dashed var(--kr-border-soft);
  font-size: 13.5px;
  line-height: 1.6;
  color: #475569;
}
.kr-steps li:first-child { border-top: 0; padding-top: 0; }

.kr-step-n {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-cap-border);
  border-radius: 3px;
  background-image: linear-gradient(to bottom, #FFFFFF 0%, #DCE9F7 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9);
  font-size: 11px;
  font-weight: 700;
  color: var(--kr-primary);
}

/* ========================================================== ADMIN SIDEBAR */

.kr-side { width: 15rem; transition: width .18s ease; }
.kr-main { margin-inline-start: 0; }
@media (min-width: 1024px) { .kr-main { margin-inline-start: 15rem; transition: margin .18s ease; } }

/* Collapsed: icons only, labels replaced by hover tooltips. */
body.kr-rail-collapsed .kr-side { width: 3.75rem; }
@media (min-width: 1024px) { body.kr-rail-collapsed .kr-main { margin-inline-start: 3.75rem; } }
body.kr-rail-collapsed .kr-nav-text,
body.kr-rail-collapsed .kr-nav-label,
body.kr-rail-collapsed .kr-brand-name,
body.kr-rail-collapsed .kr-brand-logo,
body.kr-rail-collapsed .kr-side-user-info { display: none; }
body.kr-rail-collapsed .kr-nav-item { justify-content: center; padding-inline: 0; }
body.kr-rail-collapsed .kr-rail-toggle svg { transform: rotate(180deg); }
body.kr-rail-collapsed .kr-side-user { justify-content: center; }

.kr-nav { flex: 1; overflow-y: auto; padding: .35rem .5rem .75rem; }

/* The group heading. Small, quiet, and the reason fourteen links stop being
   a wall of equal-weight text. */
.kr-nav-label {
  margin: .85rem .4rem .3rem;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #94A3B8;
}
.kr-nav-label:first-child { margin-top: .25rem; }

.kr-nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .45rem .6rem;
  border: 1px solid transparent;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 600;
  color: #475569;
  text-decoration: none;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.kr-nav-item:hover { background: var(--kr-ribbon); border-color: var(--kr-border-soft); color: var(--kr-primary); }

.kr-nav-item.is-active {
  border-color: var(--kr-border);
  color: #fff;
  background-image: linear-gradient(to bottom, var(--kr-primary-600) 0%, var(--kr-primary) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 1px 2px rgba(15, 30, 49, .18);
}

.kr-nav-icon { flex: none; display: inline-flex; }
.kr-nav-icon svg { width: 16px; height: 16px; }
.kr-nav-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.kr-nav-badge {
  flex: none;
  min-width: 17px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--kr-danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  text-align: center;
  line-height: 16px;
}
.kr-nav-item.is-active .kr-nav-badge { background: rgba(255, 255, 255, .28); }

/* Tooltip, only while the rail is collapsed. */
body.kr-rail-collapsed .kr-nav-item::after {
  content: attr(data-tip);
  position: absolute;
  inset-inline-start: calc(100% + .5rem);
  top: 50%;
  transform: translateY(-50%);
  padding: .25rem .5rem;
  border: 1px solid var(--kr-border);
  border-radius: 3px;
  background: var(--kr-cap-text);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
  z-index: 60;
}
body.kr-rail-collapsed .kr-nav-item:hover::after { opacity: 1; }

.kr-rail-toggle {
  margin-inline-start: auto;
  width: 24px; height: 24px;
  flex: none;
  display: none;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-border-soft);
  border-radius: 3px;
  background-image: linear-gradient(to bottom, #FFFFFF 0%, #E8F1FA 100%);
  color: var(--kr-primary-600);
  cursor: pointer;
}
@media (min-width: 1024px) { .kr-rail-toggle { display: inline-flex; } }
.kr-rail-toggle:hover { border-color: var(--kr-border); }
.kr-rail-toggle svg { width: 13px; height: 13px; transition: transform .18s ease; }

/* Who is signed in, at the foot of the rail. */
.kr-side-user {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .6rem .75rem;
  border-top: 1px solid var(--kr-border-soft);
  background: var(--kr-ribbon);
}
.kr-side-avatar {
  width: 28px; height: 28px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-border);
  border-radius: 4px;
  background-image: linear-gradient(to bottom, var(--kr-primary-600) 0%, var(--kr-primary) 100%);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.kr-side-user-info { min-width: 0; line-height: 1.25; }
.kr-side-user-info strong { display: block; font-size: 12.5px; color: var(--kr-cap-text); }
.kr-side-user-info small { display: block; font-size: 10.5px; color: #64748B; overflow: hidden; text-overflow: ellipsis; }

/* ============================================================ STAT TILES */

.kr-stats {
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-bottom: 1.25rem;
}
@media (min-width: 900px) { .kr-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.kr-stat {
  display: block;
  padding: .85rem .95rem;
  border: 1px solid var(--kr-border);
  border-radius: var(--kr-radius);
  background: #fff;
  box-shadow: 0 1px 2px rgba(15, 30, 49, .06), inset 0 1px 0 rgba(255, 255, 255, .9);
  text-decoration: none;
  transition: transform .18s cubic-bezier(.22,1,.36,1), box-shadow .18s ease, border-color .18s ease;
}
a.kr-stat:hover {
  transform: translateY(-2px);
  border-color: var(--kr-primary-600);
  box-shadow: 0 2px 4px rgba(15, 30, 49, .10), 0 10px 24px rgba(15, 30, 49, .12);
}

/* The coloured glyph tile — what makes a row of numbers scannable. */
.kr-stat-icon {
  width: 32px; height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--kr-border-soft);
  border-radius: 4px;
  margin-bottom: .5rem;
}
.kr-stat-icon svg { width: 16px; height: 16px; }

.kr-stat-val {
  font-family: Rubik, 'Nunito Sans', system-ui, sans-serif;
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--kr-cap-text);
  direction: ltr;
}
.kr-stat-label {
  margin-top: .3rem;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #64748B;
}
.kr-stat-sub { margin-top: .2rem; font-size: 11px; color: #94A3B8; }

/* ========================================================== THE HERO DEMO */

/* A Krypton window drawn in CSS, sitting on the dark hero band. Sized in
   relative units so it holds together from a phone to a wide desktop. */
.kr-demo {
  --demo-fg: #0F172A;
  max-width: 60rem;
  margin: 0 auto;
  border: 1px solid var(--kr-border);
  border-radius: 7px;
  background: var(--kr-panel);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .25),
              0 18px 46px rgba(0, 0, 0, .38),
              0 44px 90px rgba(0, 0, 0, .30);
  overflow: hidden;
  text-align: start;
  font-size: 13px;
  user-select: none;
}

.kr-demo-cap {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .45rem .6rem;
  border-bottom: 1px solid var(--kr-border);
  background-image: linear-gradient(to bottom, var(--kr-chrome-lit) 0%, var(--kr-chrome) 45%, var(--kr-chrome-dim) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .85);
}
.kr-demo-mark {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--kr-border); border-radius: 3px;
  background-image: linear-gradient(to bottom, var(--kr-primary-600), var(--kr-primary));
  color: #fff;
}
.kr-demo-mark svg { width: 12px; height: 12px; }
.kr-demo-title { font-size: 12px; font-weight: 700; color: var(--kr-cap-text); }
.kr-demo-title span { font-weight: 400; opacity: .75; }
.kr-demo-btns { margin-inline-start: auto; display: flex; gap: 3px; }
.kr-demo-btns i {
  width: 18px; height: 14px;
  border: 1px solid var(--kr-border-soft); border-radius: 2px;
  background: #F2F8FD;
}
.kr-demo-btns i.x { background: #F6D4D4; border-color: #DFA9A9; }

.kr-demo-ribbon {
  display: flex; gap: 2px;
  padding: .3rem .5rem 0;
  border-bottom: 1px solid var(--kr-border);
  background-image: linear-gradient(to bottom, var(--kr-ribbon), var(--kr-ribbon-dim));
}
.kr-demo-tab {
  padding: .3rem .7rem;
  border: 1px solid transparent; border-bottom: none;
  border-radius: 3px 3px 0 0;
  font-size: 11.5px; font-weight: 600; color: var(--kr-primary-600);
}
.kr-demo-tab.is-on {
  margin-bottom: -1px; padding-bottom: calc(.3rem + 1px);
  border-color: var(--kr-border); background: #fff;
  color: var(--kr-primary); font-weight: 700;
}

.kr-demo-bar {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .6rem;
  border-bottom: 1px solid var(--kr-border-soft);
  background: var(--kr-ribbon);
}
.kr-demo-lbl { font-size: 11.5px; font-weight: 700; color: var(--kr-cap-text); }
.kr-demo-field {
  display: inline-flex; align-items: center;
  min-width: 15rem; min-height: 26px;
  padding: .25rem .5rem;
  border: 1px solid var(--kr-border); border-radius: 3px;
  background: #fff;
  box-shadow: inset 0 1px 2px rgba(30, 58, 95, .1);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; letter-spacing: .04em; color: var(--demo-fg);
  direction: ltr;
}
.kr-caret {
  display: inline-block; width: 1px; height: 14px;
  margin-inline-start: 1px; background: var(--kr-primary);
  animation: kr-blink 1.1s step-end infinite;
}
@keyframes kr-blink { 50% { opacity: 0; } }

.kr-demo-go {
  padding: .25rem .7rem;
  border: 1px solid #14532D; border-radius: 3px;
  background-image: linear-gradient(to bottom, #10B981, var(--kr-accent) 55%, #047857);
  color: #fff; font-size: 11.5px; font-weight: 700;
  text-shadow: 0 1px 0 rgba(0,0,0,.18);
  transition: filter .12s ease, transform .08s ease;
}
.kr-demo-go.is-hit { filter: brightness(1.15); transform: translateY(1px); }

.kr-demo-found {
  font-size: 11.5px; font-weight: 700; color: var(--kr-ok);
  opacity: 0; transition: opacity .3s ease;
}
.kr-demo-found.is-on { opacity: 1; }

.kr-demo-grid { background: #fff; }
.kr-demo-head, .kr-demo-row {
  display: grid;
  grid-template-columns: 6.5rem 1fr 6rem 4.5rem 6rem;
  gap: .5rem;
  padding: .35rem .6rem;
  align-items: center;
}
.kr-demo-head {
  border-bottom: 1px solid var(--kr-border);
  background: var(--kr-grid-head);
  font-size: 10.5px; font-weight: 700; color: var(--kr-cap-text);
  text-transform: uppercase; letter-spacing: .03em;
}
.kr-demo-row {
  border-bottom: 1px solid #EEF2F7;
  font-size: 12px; color: #334155;
  opacity: 0; transform: translateY(-3px);
  animation: kr-row-in .28s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes kr-row-in { to { opacity: 1; transform: none; } }
.kr-demo-row .r { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--kr-primary); direction: ltr; }
.kr-demo-row .p { font-weight: 700; color: var(--kr-primary); direction: ltr; }
.kr-demo-row .s-ok  { color: var(--kr-ok); font-weight: 700; }
.kr-demo-row .s-low { color: var(--kr-warn); font-weight: 700; }
.kr-demo-row .s-no  { color: var(--kr-danger); font-weight: 700; }
.kr-demo-row.is-sel { background: var(--kr-select); }

/* Keep the frame from jumping as rows arrive. */
[data-kr-demo-rows] { min-height: 11.5rem; }

.kr-demo-status {
  display: flex; align-items: center; gap: .6rem;
  padding: .35rem .6rem;
  border-top: 1px solid var(--kr-border);
  background: var(--kr-status);
  font-size: 11px; color: var(--kr-primary-600);
}
.kr-demo-spacer { flex: 1; }
.kr-demo-offline { display: inline-flex; align-items: center; gap: .3rem; font-weight: 700; color: var(--kr-ok); }
.kr-demo-offline i { width: 6px; height: 6px; border-radius: 999px; background: var(--kr-accent); }

@media (max-width: 640px) {
  .kr-demo { font-size: 12px; }
  .kr-demo-head, .kr-demo-row { grid-template-columns: 1fr 4rem 5rem; }
  .kr-demo-head span:nth-child(2), .kr-demo-row .brand,
  .kr-demo-head span:nth-child(3), .kr-demo-row .part { display: none; }
  .kr-demo-field { min-width: 10rem; }
}

/* Anyone who has asked for less motion gets the finished state, still. */
@media (prefers-reduced-motion: reduce) {
  .kr-demo-row { animation: none; opacity: 1; transform: none; }
  .kr-caret { animation: none; opacity: 0; }
}

/* =========================================================== COOKIE NOTICE */

.kr-cookie {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 80;
  padding: .75rem;
  animation: kr-cookie-in .32s cubic-bezier(.22, 1, .36, 1);
}
.kr-cookie[hidden] { display: none; }
@keyframes kr-cookie-in { from { transform: translateY(110%); } }

.kr-cookie-inner {
  max-width: 58rem;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .8rem 1rem;
  border: 1px solid var(--kr-border);
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 2px 4px rgba(15, 30, 49, .10), 0 14px 36px rgba(15, 30, 49, .18);
}

.kr-cookie-text { flex: 1; min-width: 15rem; }
.kr-cookie-text strong {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--kr-cap-text);
  margin-bottom: .15rem;
}
.kr-cookie-text p { margin: 0; font-size: 12.5px; line-height: 1.55; color: #64748B; }

/* Both answers the same size: a refuse button that is harder to find than
   accept is not a choice, it is a dark pattern. */
.kr-cookie-actions { display: flex; gap: .5rem; flex: none; }
.kr-cookie-actions .kr-button { padding: .5rem 1.1rem; font-size: 12.5px; }

@media (max-width: 560px) {
  .kr-cookie-actions { width: 100%; }
  .kr-cookie-actions .kr-button { flex: 1; justify-content: center; }
}

/* ======================================================== CAMPAIGN EDITOR */

.kr-ed-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  padding: .4rem .5rem;
  border: 1px solid var(--kr-border);
  border-bottom: 0;
  border-radius: var(--kr-radius) var(--kr-radius) 0 0;
  background-image: linear-gradient(to bottom, var(--kr-ribbon), var(--kr-ribbon-dim));
}
.kr-ed-bar button {
  min-width: 30px;
  height: 26px;
  padding: 0 .5rem;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  font-size: 12px;
  font-weight: 700;
  color: var(--kr-primary);
  cursor: pointer;
}
.kr-ed-bar button:hover { border-color: var(--kr-border-soft); background: #fff; }
.kr-ed-bar .kr-ed-sep { width: 1px; margin: 2px 4px; background: var(--kr-border-soft); }

/* The message, shown at the width it will actually be read at. */
.kr-ed-area {
  min-height: 22rem;
  max-height: 40rem;
  overflow-y: auto;
  padding: 1.2rem;
  border: 1px solid var(--kr-border);
  border-radius: 0 0 var(--kr-radius) var(--kr-radius);
  background: #fff;
  font-family: 'Segoe UI', 'Nunito Sans', Tahoma, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.75;
  color: #0F172A;
  outline: none;
}
.kr-ed-area:focus { box-shadow: inset 0 0 0 2px rgba(42, 81, 131, .14); }
.kr-ed-area img { max-width: 100%; height: auto; }
.kr-ed-area a { color: var(--kr-accent); }
.kr-ed-area h2 { font-size: 19px; font-weight: 700; color: var(--kr-cap-text); margin: .8rem 0 .5rem; }
.kr-ed-area ul, .kr-ed-area ol { padding-inline-start: 1.3rem; }
.kr-ed-area:empty::before {
  content: attr(data-placeholder);
  color: #94A3B8;
}

/* Template cards */
.kr-tpl-grid { display: grid; gap: .5rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { .kr-tpl-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.kr-tpl {
  text-align: start;
  padding: .6rem .7rem;
  border: 1px solid var(--kr-border-soft);
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  transition: border-color .15s ease, transform .1s ease;
}
.kr-tpl:hover { border-color: var(--kr-primary-600); transform: translateY(-1px); }
.kr-tpl strong { display: block; font-size: 13px; color: var(--kr-cap-text); }
.kr-tpl small { display: block; margin-top: .15rem; font-size: 11.5px; color: #64748B; line-height: 1.45; }

/* Image library grid in the Images tab */
.kr-media-grid { display: grid; gap: .6rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 700px) { .kr-media-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.kr-media {
  border: 1px solid var(--kr-border-soft);
  border-radius: 4px;
  background: #fff;
  overflow: hidden;
}
.kr-media img { display: block; width: 100%; height: 96px; object-fit: contain; background: #F7FAFD; }
.kr-media-foot { padding: .4rem .5rem; border-top: 1px solid var(--kr-border-soft); font-size: 10.5px; color: #64748B; }
.kr-media-foot code { display: block; word-break: break-all; font-size: 9.5px; color: var(--kr-primary-600); }

/* ====================================================== MODDIALOGSTYLE SKIN
   The site adopts the dialog identity of the software: a bandeau strip for
   navigation, blue as the action colour, and the same button treatment —
   solid CBleu, CBleuFonce border, 3px rounding, white semibold label, with
   the darker shade on hover and the darkest when pressed.

   Green is kept only where it means something: a success message, an
   in-stock value, the WhatsApp button. A colour that means "go" everywhere
   means nothing anywhere.
   ======================================================================== */

/* ---- the menu strip ---------------------------------------------------- */

/* Hidden on small screens, shown from the large breakpoint up — declared
   here rather than with Tailwind utilities, because app.css is pre-compiled
   and only contains the classes that were used when it was built. A utility
   that is not in that file silently does nothing, which is how this strip
   first shipped invisible at every width. */
.kr-topstrip {
  display: none;
  border-bottom: 1px solid var(--md-trait);
  background: var(--md-bandeau);
}
@media (min-width: 1024px) {
  .kr-topstrip { display: block; }
}
.kr-topstrip-inner {
  display: flex;
  align-items: center;
  gap: .35rem;
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 1.25rem;
  min-height: 42px;
}

/* A menu entry, painted like a Krypton toolbar item. */
.kr-menu-item {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .45rem .8rem;
  border: 1px solid transparent;
  border-radius: 3px;
  font-family: 'Segoe UI', 'Nunito Sans', system-ui, sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--md-texte);
  text-decoration: none;
  white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.kr-menu-item:hover {
  border-color: var(--md-trait);
  background: #fff;
  color: var(--md-bleu);
}
.kr-menu-item.is-active {
  border-color: var(--md-trait);
  background: #fff;
  color: var(--md-bleu);
  font-weight: 700;
}
.kr-menu-item svg { width: 15px; height: 15px; flex: none; }

.kr-menu-sep { width: 1px; align-self: stretch; margin: .45rem .35rem; background: var(--md-trait); }
.kr-menu-end { margin-inline-start: auto; display: flex; align-items: center; gap: .4rem; }

/* ---- buttons: blue, exactly as BoutonPrincipal paints them -------------- */

.btn-accent,
.kr-button-primary,
.kr-submit,
.kr-button-navy {
  background-image: none !important;
  background-color: var(--md-bleu) !important;
  border: 1px solid var(--md-bleu-fonce) !important;
  border-radius: 3px !important;
  color: #fff !important;
  font-weight: 700;
  text-shadow: none !important;
  box-shadow: none !important;
}
.btn-accent:hover,
.kr-button-primary:hover,
.kr-submit:hover,
.kr-button-navy:hover {
  background-color: var(--md-bleu-fonce) !important;
  filter: none !important;
}
.btn-accent:active,
.kr-button-primary:active,
.kr-submit:active,
.kr-button-navy:active {
  background-color: var(--md-bleu-press) !important;
}

/* BoutonSecondaire: white, quiet border, dark text. */
.btn-outline,
.kr-button {
  border-radius: 3px;
}
.kr-button:not(.kr-button-primary):not(.kr-button-navy):not(.kr-button-danger) {
  background-image: none;
  background-color: #fff;
  border-color: var(--md-trait);
  color: var(--md-texte);
}
.kr-button:not(.kr-button-primary):not(.kr-button-navy):not(.kr-button-danger):hover {
  background-image: none;
  background-color: var(--md-bandeau);
  border-color: var(--md-trait);
}

/* ---- headings and links follow the blue ------------------------------- */

.kicker { color: var(--md-bleu) !important; }
.kr-panel-cap,
.kr-form-cap,
.kr-dialog-cap { color: var(--md-bleu); }
.kr-stat-val, .kr-brand-name { color: var(--md-texte); }

/* The admin rail's selected item, in the dialog blue. */
.kr-nav-item.is-active {
  background-image: none;
  background-color: var(--md-bleu);
  border-color: var(--md-bleu-fonce);
}
.kr-nav-item:hover { color: var(--md-bleu); }

/* Section captions echo the KryptonHeaderGroup heading. */
.kr-panel-cap,
.kr-form-cap {
  background-image: none;
  background-color: var(--md-bandeau);
  border-bottom-color: var(--md-trait);
}
.kr-tabstrip {
  background-image: none;
  background-color: var(--md-bandeau);
  border-color: var(--md-trait);
}
.kr-tabstrip a { color: var(--md-gris); }
.kr-tabstrip a.is-active { color: var(--md-bleu); border-color: var(--md-trait); }

/* ---- what stays green, and why --------------------------------------- */
/* success alerts, stock states and the WhatsApp button carry meaning in
   their colour; they are deliberately left alone. */
.kr-pill-on, .alert-success, .kr-demo-offline, .s-ok { }

/* The "most popular" plan: brand accent, so it follows the dialog blue. */
.kr-popular { background-color: var(--md-bleu); }
.kr-plan-featured {
  border-color: var(--md-bleu) !important;
  box-shadow: 0 0 0 1px rgba(21, 101, 192, .18),
              0 4px 12px rgba(15, 23, 42, .07),
              0 12px 28px rgba(15, 23, 42, .07);
}

/* ---- the header picture ------------------------------------------------
   Fills the empty stretch of the top bar. It is decorative, so it is marked
   aria-hidden and given an empty alt: a screen reader should not read out a
   picture that carries no information the text does not already give.
   Hidden below the large breakpoint, where that space does not exist. */
/* The picture takes the whole middle of the bar and centres itself in it,
   so the brand stays hard left and the language + trial button stay hard
   right. Growing the middle rather than nudging with margins keeps all
   three anchored whatever the logo or tagline width happens to be. */
/* On a phone the top bar has no spare width, so the picture gets its own
   centred row underneath it instead of being dropped altogether — hiding it
   there meant the one place most customers actually browse from never saw
   it at all. */
.kr-header-img {
  display: flex;
  order: 9;
  width: 100%;
  justify-content: center;
  padding: .55rem 1rem .1rem;
  line-height: 0;
}
.kr-header-img img { max-height: 34px; }
@media (min-width: 1024px) {
  /* Centred on the BAR, not on the gap between the brand and the controls.
     Growing a middle flex item centres it in whatever space is left over,
     which lands off-centre the moment the two sides differ in width — it
     was 84px right of true centre. Taking it out of the flow and pinning it
     to 50% makes it independent of both. */
  .kr-header-img {
    display: flex;
    align-items: center;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    order: 0;
    width: auto;
    padding: 0;
    pointer-events: none;
  }
  .kr-header-img img { max-height: none; }
  a.kr-header-img { pointer-events: auto; }
}
.kr-header-img img {
  display: block;
  width: auto;
  max-width: 46vw;
  object-fit: contain;
}
a.kr-header-img { transition: opacity .15s ease; }
a.kr-header-img:hover { opacity: .85; }

/* The header picture again in the footer, under the tagline. Wider column
   there, so it may run to the full width of that block. */
.kr-footer-img {
  display: block;
  margin-top: 1.1rem;
  max-width: 24rem;
  line-height: 0;
}
.kr-footer-img img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
}
a.kr-footer-img { transition: opacity .15s ease; }
a.kr-footer-img:hover { opacity: .85; }

/* ---- accent leftovers ---------------------------------------------------
   These Tailwind accent utilities are the brand colour, not a status, so
   they follow the switch to CBleu. Semantic greens use their own classes
   (kr-pill-on, alert-success, s-ok) and are untouched. */
.text-accent          { color: var(--md-bleu) !important; }
.hover\:text-accent:hover   { color: var(--md-bleu) !important; }
.hover\:border-accent:hover { border-color: var(--md-bleu) !important; }
.bg-accent            { background-color: var(--md-bleu) !important; }
.bg-accent\/10        { background-color: rgba(21, 101, 192, .10) !important; }
.ring-accent\/30      { --tw-ring-color: rgba(21, 101, 192, .30) !important; }
.focus\:ring-accent\/30:focus { --tw-ring-color: rgba(21, 101, 192, .30) !important; }
.focus\:border-accent:focus   { border-color: var(--md-bleu) !important; }

/* Language switcher + trial button: always the far right of the bar.
   ms-auto alone stopped being enough once the middle started growing, and
   the old lg:ms-0 actively cancelled it at desktop width — which is where
   the picture pushed them off-centre. */
.kr-header-end {
  flex: 0 0 auto;
  margin-inline-start: auto;
}

/* The bar is the positioning context for the centred picture. */
header nav { position: relative; flex-wrap: wrap; }
@media (min-width: 1024px) { header nav { flex-wrap: nowrap; } }

/* ---- orbit labels on small screens --------------------------------------
   These are absolutely positioned with white-space:nowrap, so a long one
   near the right edge pushed the document 49px wider than the viewport and
   every phone visitor could scroll the whole site sideways. They are shown
   on interaction, which a touch screen has no equivalent of, and the orbit
   is cramped at that size anyway — so they are dropped below the desktop
   breakpoint rather than clipped, which would leave half-words on screen. */
@media (max-width: 1023px) {
  .orbit-label { display: none !important; }
}

/* ---- social marks -------------------------------------------------------
   Grey at rest so a row of six brand colours does not shout louder than the
   page, and each takes its own colour on hover — which also confirms the
   link is live. */
.kr-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--md-trait);
  border-radius: 4px;
  background: #fff;
  color: #94A3B8;
  transition: color .15s ease, border-color .15s ease, transform .15s ease;
}
.kr-social svg { width: 17px; height: 17px; }
.kr-social:hover {
  color: var(--brand, var(--md-bleu));
  border-color: var(--brand, var(--md-bleu));
  transform: translateY(-1px);
}

/* ---------------------------------------------------------------- status --
   The connection light in the dashboard footer. Green while the database is
   answering and the browser is online, red the moment either stops being
   true — an empty table then reads as "nothing to show" rather than as a
   failure the operator never saw.
*/
.kr-status{display:inline-flex;align-items:center;gap:.4rem;font-weight:600}
.kr-status-dot{width:8px;height:8px;border-radius:50%;flex:none;box-shadow:0 0 0 2px #fff}
.kr-status-dot.is-ok{background:#16A34A;box-shadow:0 0 0 2px #fff,0 0 0 3px rgba(22,163,74,.25);
  animation:kr-pulse 2.4s ease-in-out infinite}
.kr-status-dot.is-bad{background:#DC2626;box-shadow:0 0 0 2px #fff,0 0 0 3px rgba(220,38,38,.25)}
.kr-status:has(.is-bad){color:#B91C1C}
@keyframes kr-pulse{0%,100%{opacity:1}50%{opacity:.45}}
@media (prefers-reduced-motion:reduce){.kr-status-dot.is-ok{animation:none}}

/* ------------------------------------------------------------ price pair --
   Two figures on the home page instead of the old three-tier table: the
   starting licence and the complete parts version. The choice itself is made
   in the quote, where every option is priced as it is ticked.
*/
.kr-price-card{
  background:#fff;border:1px solid var(--kr-trait,#D6E0EC);border-radius:14px;
  padding:1.6rem 1.5rem;text-align:center;
  box-shadow:0 1px 2px rgba(16,40,80,.05);
}
.kr-price-card.is-full{
  border-color:var(--kr-bleu,#1565C0);
  box-shadow:0 6px 22px rgba(21,101,192,.13);
}
.kr-price-cap{
  font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--kr-gris,#6E7C91);margin:0;
}
.kr-price-fig{
  margin:.5rem 0 .1rem;font-size:2.35rem;line-height:1.1;font-weight:800;
  letter-spacing:-.02em;color:var(--kr-texte,#1C283A);
}
.kr-price-card.is-full .kr-price-fig{color:var(--kr-bleu,#1565C0)}
.kr-price-note{margin:.55rem 0 0;font-size:14px;line-height:1.6;color:#64748B}
.kr-button-lg{font-size:15px;padding:.85rem 2rem}
@media (max-width:640px){ .kr-price-fig{font-size:2rem} }

/* A ceiling discount line in the quote summary: it is money coming off, so it
   should not read like another thing being bought. */
.kr-quote-lines li.is-discount{color:#15803D;font-weight:600}
.kr-quote-lines li.is-discount .kr-line-amt{color:#15803D}

/* ------------------------------------------------------------ logo band --
   Brand and partner logos sliding under the figures on the home page.

   The track holds the list twice and moves left by exactly half its width,
   then restarts — with two identical copies the restart lands on the same
   picture, so the loop has no visible seam. Percentages are used rather than
   pixels so it works whatever the logos measure.
*/
.kr-logos{ margin-top:3rem; }
.kr-logos-title{
  margin:0 0 1.1rem;text-align:center;font-size:12px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--kr-gris,#6E7C91);
}

/* The window fades at both edges so logos arrive and leave instead of being
   chopped off by the container. */
.kr-logos-window{
  overflow:hidden;position:relative;
  -webkit-mask-image:linear-gradient(to right,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(to right,transparent,#000 8%,#000 92%,transparent);
}

/* The track lays several identical groups end to end and slides by exactly
   one of them. The gap lives INSIDE the group (with a trailing one), so every
   group is the same width and the restart lands on the same picture. Putting
   the gap on the track instead leaves the space between copies uncounted, and
   the loop jumps by half a gap on every pass. */
.kr-logos-track{
  display:flex;align-items:center;gap:0;width:max-content;
  animation:kr-logos-slide var(--kr-logos-time,35s) linear infinite;
  will-change:transform;
}
.kr-logos-group{
  display:flex;align-items:center;gap:3.5rem;
  padding-inline-end:3.5rem;      /* the seam between one copy and the next */
  flex:none;
}
@keyframes kr-logos-slide{
  from{ transform:translateX(0); }
  to  { transform:translateX(var(--kr-logos-shift,-50%)); }
}

/* Arabic reads right to left, so the band travels the other way to match. */
[dir="rtl"] .kr-logos-track{ animation-name:kr-logos-slide-rtl; }
@keyframes kr-logos-slide-rtl{
  from{ transform:translateX(var(--kr-logos-shift,-50%)); }
  to  { transform:translateX(0); }
}

.kr-logo{ flex:none;display:flex;align-items:center;justify-content:center; }
.kr-logo img{
  height:44px;width:auto;max-width:170px;object-fit:contain;display:block;
  transition:filter .25s ease, opacity .25s ease, transform .25s ease;
}

/* Muted by default so a wall of competing brand colours does not fight the
   page; full colour when the visitor points at one. */
.kr-logos.is-muted .kr-logo img{ filter:grayscale(1);opacity:.62; }
.kr-logos.is-muted .kr-logo img:hover{ filter:none;opacity:1;transform:scale(1.04); }
.kr-logos:not(.is-muted) .kr-logo img:hover{ transform:scale(1.04); }

/* Pausing on hover lets someone actually read a logo they noticed. */
.kr-logos-window:hover .kr-logos-track{ animation-play-state:paused; }

@media (max-width:640px){
  .kr-logos-group{ gap:2.25rem;padding-inline-end:2.25rem; }
  .kr-logo img{ height:34px;max-width:130px; }
}

/* Movement is decorative; for anyone who has asked for less of it the band
   becomes a plain centred row that wraps. */
@media (prefers-reduced-motion:reduce){
  .kr-logos-track{ animation:none;width:auto;justify-content:center; }
  .kr-logos-group{ flex-wrap:wrap;justify-content:center;padding-inline-end:0; }
  .kr-logos-window{ -webkit-mask-image:none;mask-image:none; }
  .kr-logos-group[aria-hidden="true"]{ display:none; }   /* one copy is enough */
}

/* ------------------------------------------------------------ legal pages --
   A privacy policy is read by someone deciding whether to trust you, usually
   while scanning for one specific answer. So each section is its own Krypton
   window with its heading in the caption bar: the page becomes a list you can
   search with your eyes instead of a wall of text.
*/
.kr-legal .kr-legal-window{ margin-bottom:1.1rem; }
.kr-legal .kr-legal-body{ padding:1.15rem 1.3rem; }
.kr-legal .kr-legal-body p{
  margin:0 0 .8rem; font-size:15px; line-height:1.75; color:#475569;
}
.kr-legal .kr-legal-body p:last-child{ margin-bottom:0; }
.kr-legal .kr-legal-body strong{ color:var(--kr-texte,#1C283A); font-weight:700; }

/* Bullets drawn with a mark rather than a list, so the little format stays
   line-based and an editor cannot break the nesting. */
.kr-legal .kr-legal-item{
  position:relative; padding-inline-start:1.15rem;
}
.kr-legal .kr-legal-item::before{
  content:''; position:absolute; inset-inline-start:.15rem; top:.62em;
  width:5px; height:5px; border-radius:50%; background:var(--kr-bleu,#1565C0);
}
.kr-legal .kr-legal-intro{
  margin:0 0 1.5rem; font-size:16px; line-height:1.8; color:#475569;
}
@media (max-width:640px){
  .kr-legal .kr-legal-body{ padding:1rem; }
  .kr-legal .kr-legal-body p{ font-size:14.5px; }
}

/* A removable chip: the country stays readable, the × only shows intent on
   hover so the row does not look like a wall of delete buttons. */
.kr-chip{
  display:inline-flex;align-items:center;gap:.45rem;cursor:pointer;
  border:1px solid var(--kr-trait,#D6E0EC);background:#fff;border-radius:999px;
  padding:.38rem .55rem .38rem .8rem;font-size:13px;font-weight:600;
  color:var(--kr-texte,#1C283A);transition:border-color .15s,background .15s,color .15s;
}
.kr-chip:hover{ border-color:#FCA5A5;background:#FEF2F2;color:#B91C1C; }
.kr-chip-code{
  font-size:11px;font-weight:700;letter-spacing:.03em;color:var(--kr-gris,#6E7C91);
}
.kr-chip:hover .kr-chip-code{ color:#DC2626; }
.kr-chip-x{
  display:inline-flex;align-items:center;justify-content:center;
  width:16px;height:16px;border-radius:50%;font-size:13px;line-height:1;
  background:#EEF3F9;color:var(--kr-gris,#6E7C91);
}
.kr-chip:hover .kr-chip-x{ background:#DC2626;color:#fff; }

/* Where a visitor arrived from, shown beside their address in the list. */
.kr-src{
  display:inline-block;margin-inline-start:.4rem;padding:.05rem .4rem;
  border-radius:4px;background:#EEF3F9;color:var(--kr-gris,#6E7C91);
  font-size:11px;font-weight:600;white-space:nowrap;
}

/* ------------------------------------------------------------ stat tiles --
   The four headline numbers. Each carries its own change against the period
   before, because a number without a comparison tells you nothing.
*/
.kr-trend-row{ display:grid;gap:.9rem;grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (min-width:900px){ .kr-trend-row{ grid-template-columns:repeat(4,minmax(0,1fr)); } }
.kr-trend{
  background:#fff;border:1px solid var(--kr-trait,#D6E0EC);border-radius:12px;
  padding:1rem 1.1rem;box-shadow:0 1px 2px rgba(16,40,80,.04);
}
.kr-trend-label{
  margin:0;font-size:11.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--kr-gris,#6E7C91);
}
.kr-trend-value{
  margin:.35rem 0 .1rem;font-size:1.9rem;line-height:1.1;font-weight:800;
  letter-spacing:-.02em;color:var(--kr-texte,#1C283A);
}
.kr-trend-change{ margin:0;font-size:12px;font-weight:600; }

/* ---------------------------------------------------------- upload bar --
   Large installers take minutes to upload. Without this the page looks dead
   and people press the button again, starting the whole thing over.
*/
.kr-upload{ margin-top:1rem; }
.kr-upload-track{
  height:8px;border-radius:4px;background:#EEF3F9;overflow:hidden;
}
.kr-upload-fill{
  height:100%;width:0;border-radius:4px;background:var(--kr-bleu,#1565C0);
  transition:width .2s linear;
}
.kr-upload-text{
  margin:.45rem 0 0;font-size:12.5px;font-weight:600;color:var(--kr-gris,#6E7C91);
}
.kr-upload.is-bad .kr-upload-fill{ background:#DC2626; }
.kr-upload.is-bad .kr-upload-text{ color:#B91C1C; }

/* ---------------------------------------------------------------------------
   A row of fields with the buttons that act on them.

   The buttons have to sit on the same line as the boxes and be exactly as
   tall: a button a few pixels taller than the field beside it is the sort of
   thing you cannot un-see. So every control in the row shares one height, and
   any hint text is taken out of the row and dropped underneath it — otherwise
   the hint stretches its own column and pushes the buttons out of line.
--------------------------------------------------------------------------- */
.kr-field-row{
  display:flex; flex-wrap:wrap; gap:.6rem; align-items:flex-end;
}
/* `kr-cell`, not `kr-field`: the compiled Tailwind sheet already owns
   `.kr-field` and would put a border and padding around the column. */
.kr-field-row > .kr-cell{ display:flex; flex-direction:column; min-width:13rem; }
.kr-field-row .kr-label{ margin-bottom:.3rem; }
.kr-field-row .kr-input,
.kr-field-row .kr-select,
.kr-field-row .kr-button{ height:2.3rem; }
.kr-field-row .kr-input,
.kr-field-row .kr-select{ padding-top:0; padding-bottom:0; line-height:2.2rem; }
.kr-field-row .kr-hint{ flex-basis:100%; margin-top:.45rem; }
@media (max-width:640px){
  /* On a phone each box takes the whole width rather than sitting at its
     minimum and leaving a ragged right edge. */
  .kr-field-row > .kr-cell{ flex:1 1 100%; min-width:0; }
}
