/* Portal layout — the shell and the page patterns the portal redesign introduces.
 *
 * Layers on top of static/css/organic.css, which stays the design system: this
 * file defines no colours, type or spacing of its own, only arrangement, and
 * every value it does carry comes from an Organic token. If you find yourself
 * about to write a hex here, the token is missing from organic.css and belongs
 * there instead.
 *
 * Loaded by templates/base.html, so it serves every origin that renders it — the
 * portal in full, and the account/auth screens the admin and product origins
 * borrow from it.
 *
 * Three sections:
 *   1. Shell            — header, context bars, main column, footer.
 *   2. Page patterns    — the redesign's tiles, rows, tabs and stat cells.
 *   3. Compatibility    — the class names screens outside the redesign still use,
 *                         re-expressed on Organic tokens so no page is left
 *                         unstyled by the move off main.css. Retire an entry here
 *                         when its screens are rebuilt on the patterns above.
 */

/* ══════════════════════════════════════════════════════════════════════════
   1. Shell
   ══════════════════════════════════════════════════════════════════════════ */

/* One measure for the whole origin. Wider than main.css's 960px because the
   redesign puts product tiles and six-column admin tables on the same column. */
.shell {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 var(--space-8);
}

/* Sticky and translucent. Organic draws no rule under the header — the blur
   and the ground showing through are what separate it from the page, so a
   border here would be the one hard edge in the whole shell. */
.site-header {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(10px);
}

.header-inner {
  min-height: 66px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-6);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  text-decoration: none;
  color: var(--color-text);
}
.brand:hover { color: var(--color-text); }
.brand-mark { width: 36px; height: 36px; padding: 7px 9px; border-radius: calc(var(--radius-md) * 0.75); }

/* The organisation's initial on the organisation's own colour. The letter is
   light because the branding defaults are both dark (#006593 / #162c55) and the
   branding form offers a colour picker, not a contrast check — an organisation
   that picks a pale colour gets a pale tile. If that turns out to happen, the
   fix belongs in the form as a validated minimum contrast against white, not in
   a CSS guess about which way round the pair should go. */
.brand-initial {
  width: 36px; height: 36px; flex: none;
  display: grid; place-items: center;
  border-radius: calc(var(--radius-md) * 0.75);
  background: var(--org-color); color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1;
}

.brand-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; line-height: 1.2;
}
.brand-name--nilsaro { letter-spacing: 0.06em; text-transform: uppercase; }

/* The organisation's colour as a rule under the header — the second and last
   place the chrome wears it. Only drawn when an organisation has set a display
   name, so an organisation still on the defaults gets the Nilsaro lockup and no
   rule rather than a stripe of our blue pretending to be theirs.
 *
 * No longer full-bleed. A hard-edged band running edge to edge was the only
 * straight line left on the page, and under a translucent sticky header it read
 * as a seam rather than as the organisation's colour. Inset to the content
 * column and rounded, it belongs to the same system as everything below it. */
.brand-rule {
  height: 5px;
  max-width: 1160px;
  margin: 0 auto;
  border-radius: 999px;
  background: var(--org-color);
}

/* A pill group, not a row of links: the nav is a single soft object floating on
   the ground, and each destination is a pill inside it. */
.main-nav {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 4px;
  padding: 5px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
  font-size: 14px;
}
.main-nav a {
  padding: 9px 18px; border-radius: 999px;
  color: var(--color-text); text-decoration: none; font-weight: 600;
  transition: background 0.15s;
}
.main-nav a:hover { background: var(--color-accent-200); color: var(--color-text); }
.main-nav a[aria-current="page"] { background: var(--color-accent-200); }

/* The account cluster sits outside the pill, hard right. */
.nav-account { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.nav-quiet { color: var(--color-neutral-700); }

/* A circular target for the bell, sized to the 44px minimum a thumb needs. The
   badge is positioned against it, so it needs the containing block. */
.nav-bell {
  position: relative;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--color-text);
  transition: background 0.15s;
}
.nav-bell:hover { background: var(--color-accent-200); color: var(--color-text); }
.nav-bell .nav-badge { position: absolute; top: 3px; right: 2px; }

.nav-profile {
  display: flex; align-items: center; gap: 9px;
  padding: 4px 14px 4px 4px;
  border-radius: 999px;
  color: var(--color-text); text-decoration: none;
  font-size: 14px; font-weight: 600;
  transition: background 0.15s;
}
.nav-profile:hover { background: var(--color-accent-200); color: var(--color-text); }
.nav-avatar {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-accent); color: var(--color-bg);
  font-size: 13px; font-weight: 700;
}

/* Kept for templates outside the portal shell that still emit it. */
.nav-notifications { display: inline-flex; align-items: center; gap: 7px; }
.nav-badge {
  min-width: 18px; height: 18px; padding: 0 5px;
  display: grid; place-items: center;
  border-radius: 999px;
  background: var(--color-accent); color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; line-height: 1;
  box-shadow: 0 0 0 2px var(--color-bg);
}
/* Organic separates with space, not with strokes. The rule is kept in the
   markup for templates that still emit it, and drawn as nothing. */
.nav-rule { display: none; }

/* — context bars — */
/* Support runs on the accent because it is the platform speaking, and it sits
   above the organisation bar: the fact that this is a support session outranks
   which organisation it is a session in. */
/* A pill on the page rather than a band across it — see .support-bar-inner for
   the rounding; the bar itself only carries the measure. */
.support-bar { color: var(--color-accent-800); }
.support-bar-inner {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3) 14px;
  padding: 10px 12px 10px 10px;
  border-radius: 999px;
  background: var(--color-accent-100);
  font-size: 13px;
}
.support-chip {
  background: var(--color-accent); color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; line-height: 1; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 5px var(--space-3);
  border-radius: 999px;
}
.support-end { margin-left: auto; color: var(--color-accent-800); }

.context-bar { padding-top: var(--space-2); }
.context-bar-inner {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3);
  padding-block: 9px;
  font-size: 13px;
}
.context-label {
  font-size: 11px; font-weight: 600; line-height: 1;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.context-org { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }

.main-content { padding: 36px var(--space-8) 72px; min-height: 60vh; }

.site-footer {
  padding: var(--space-6) 0 var(--space-8);
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.site-footer p { margin: 0; }

/* — flash messages — */
.messages { list-style: none; padding: 0; margin: 0 0 var(--space-6); }
.message {
  padding: 14px var(--space-6);
  margin-bottom: var(--space-2);
  border-radius: 999px;
  background: var(--color-neutral-100);
  font-size: 14px;
}
.message-success { background: var(--color-accent-2-100); color: var(--color-accent-2-800); }
.message-info { background: var(--color-accent-100); color: var(--color-accent-800); }
.message-warning { background: var(--color-warning-100); color: var(--color-warning-800); }
.message-error { background: var(--color-danger-100); color: var(--color-danger-800); }

/* ══════════════════════════════════════════════════════════════════════════
   2. Page patterns
   ══════════════════════════════════════════════════════════════════════════ */

/* — the home greeting — */
/* The largest type on any portal screen, and the only heading that is a
   sentence rather than a label. The meta line above it is deliberately quiet:
   it answers "where am I" so the greeting does not have to. */
.home-head { margin: var(--space-3) 0 36px; }
.home-meta {
  margin: 0 0 6px;
  font-size: 15px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.home-greeting { font-size: 54px; margin: 0; letter-spacing: -0.02em; }
@media (max-width: 599px) { .home-greeting { font-size: 38px; } }

/* — page and section headings — */
.page-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 20px;
  margin-bottom: 28px;
}
.page-head h1 { font-size: 46px; margin: 0; }
.page-head .card-kicker + h1 { margin-top: 6px; }
.page-head-note {
  margin: 0 0 var(--space-1);
  max-width: 420px;
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.page-head-actions { margin-left: auto; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

.page-intro {
  margin: 0 0 26px;
  max-width: 560px;
  font-size: 14px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.section-head { font-size: 24px; margin: 0 0 var(--space-3); }

/* — the modular grid — */
/* Under Modernist each cell drew its own 2px ring and the cells sat 2px apart,
   because a background showing through the gaps cannot paint the leftover space
   an auto-fit grid leaves on its last row — five contacts in three columns came
   out as five panels and one stray rectangle.
 *
 * Organic does not draw that rule at all. Cells are separated by real space and
 * lifted off the ground with elevation, so the leftover-space problem the ring
 * solved cannot arise: there is nothing to paint. The ring is gone with it. */
.cell-grid {
  display: grid;
  gap: var(--space-3);
}
.cell-grid > * {
  background: var(--color-neutral-100);
  border-radius: calc(var(--radius-lg) * 1.15);
  box-shadow: var(--shadow-sm);
}
.cell-grid--tiles { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.cell-grid--stats { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.cell-grid--panels { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.cell-grid--panels > * { padding: var(--space-6); }

/* — product tiles — */
/* The tile is the page's largest soft shape. It takes a tinted ground from the
   accent ramps rather than the neutral .cell-grid cell, so the products read as
   two distinct voices — terracotta and sage — rather than as rows of one card.
   Hover lifts rather than recolours: the ground is already carrying meaning,
   so raising it is the move left. */
.tile {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 14px;
  padding: var(--space-8);
  border-radius: calc(var(--radius-lg) * 1.45);
  background: var(--color-accent-100);
  text-decoration: none;
  color: var(--color-text);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
a.tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
}
/* The second voice. */
.tile--alt { background: var(--color-accent-2-100); }
/* A product the organisation does not have: no ground at all, just an outline,
   so it reads as a space where something could be rather than as a thing. */
.tile--empty {
  background: transparent;
  border: 2px dashed var(--color-neutral-400);
  box-shadow: none;
}
/* The primary product gets both cells on a two-up row. Below the breakpoint the
   grid is single-column anyway and the span would leave an empty second track. */
.tile--wide { grid-column: span 2; min-width: 0; }
@media (max-width: 719px) { .tile--wide { grid-column: span 1; } }

.tile--disabled { opacity: 0.55; cursor: default; }
.tile--empty .tile-name { color: var(--color-neutral-700); }

.tile-head { display: flex; align-items: flex-start; gap: var(--space-4); }
.tile-head--compact { align-items: center; gap: var(--space-3); }

.tile-badge {
  width: 64px; height: 64px; flex: none;
  display: grid; place-items: center;
  border-radius: calc(var(--radius-lg) * 0.8);
  background: var(--color-accent); color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 30px; line-height: 1;
}
.tile-badge--sm {
  width: 52px; height: 52px; font-size: 24px;
  border-radius: calc(var(--radius-lg) * 0.64);
}
.tile-badge--alt { background: var(--color-accent-2); }
.tile-badge--muted { background: var(--color-neutral-200); color: var(--color-neutral-600); }
.tile-badge--empty { background: var(--color-neutral-200); color: var(--color-neutral-600); }

.tile-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 40px; line-height: 1.05; letter-spacing: -0.015em;
}
.tile-name--sm { font-size: 28px; line-height: 1.1; }
.tile-desc {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.tile-headings { min-width: 0; }
.tile-head .tile-desc { margin-top: var(--space-1); }
a.tile-name { text-decoration: none; color: var(--color-text); }
a.tile-name:hover { color: var(--color-accent-700); }
.grid-footnote {
  font-size: 12px; margin: 14px 0 0;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.tile-open {
  margin-left: auto;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; line-height: 1;
  color: var(--color-accent-700);
  white-space: nowrap;
}
.tile-head .tile-open { padding-top: 6px; }
.tile-tags { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }

/* Deep links into the product, so the common task is one click from sign-in
   rather than a landing page away. Anchors nested in the tile anchor would be
   invalid HTML, so the tile is not itself a link when it carries these — see
   templates/core/app_launcher.html. */
.tile-quicks { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.quick {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 11px 18px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
  font-size: 14px; font-weight: 600;
  text-decoration: none;
  color: var(--color-text);
  transition: background 0.15s, transform 0.15s;
}
.quick:hover { background: var(--color-bg); color: var(--color-text); transform: translateY(-2px); }
.quick svg { color: var(--color-accent-700); }

/* — list rows — */
/* Under Modernist these were separated by a rule. Organic has no hairlines to
   spend, so each row becomes its own low, wide, rounded surface and the gap
   between them does the separating. */
.listrow {
  display: flex; gap: var(--space-4);
  padding: 18px 22px;
  margin-bottom: var(--space-2);
  border-radius: var(--radius-lg);
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
  align-items: center;
}
.listrow:last-child { margin-bottom: 0; }
.listrow-main { flex: 1; min-width: 0; }
.listrow-title { font-weight: 600; font-size: 15px; }
.listrow-meta {
  font-size: 12px; margin-top: 3px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.listrow-dot { width: 10px; height: 10px; flex: none; border-radius: 50%; background: var(--color-neutral-400); }
.listrow-dot--unread { background: var(--color-accent); }
.listrow--unread .listrow-title { font-weight: 600; }
.listrow--read .listrow-title { font-weight: 400; }

.listrow-strip { margin-top: var(--space-4); }

/* — tab navigation — */
/* The same pill group as .main-nav, at the page level. An underlined tab row
   is a hairline pattern and Organic does not draw one. */
.tab-nav {
  display: inline-flex; flex-wrap: wrap; gap: 4px;
  padding: 5px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
}
.tab {
  text-decoration: none;
  color: var(--color-text);
  font-family: var(--font-body); font-weight: 600;
  font-size: 14px; line-height: 1;
  padding: 9px 18px;
  border-radius: 999px;
  transition: background 0.15s;
}
.tab:hover { background: var(--color-accent-200); color: var(--color-text); }
.tab[aria-current="page"] { background: var(--color-accent-200); color: var(--color-text); }

/* — the organisation admin area — */
.admin-head { margin-bottom: 26px; }
.admin-head h1 { font-size: 40px; margin: 6px 0 20px; }
.admin-subtitle { font-size: 26px; margin: 0 0 var(--space-4); }
.admin-stats { margin-bottom: 36px; }
.admin-lede {
  margin: 0 0 20px; max-width: 620px; font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
/* The row above a table: what this screen is, and the action that changes it. */
.admin-bar {
  display: flex; flex-wrap: wrap; gap: 14px;
  align-items: flex-end;
  margin-bottom: 20px;
}
.admin-bar-note {
  margin: 0; max-width: 560px; font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.admin-bar .page-head-actions { margin-left: auto; }
.admin-table { margin-bottom: var(--space-4); }
.table-footnote { margin: var(--space-3) 0 var(--space-6); font-size: 13px; }
.cell-strong { font-weight: 600; }
.section-head--spaced { margin-top: 36px; }
.swatch {
  display: inline-block; width: 14px; height: 14px;
  margin-right: 6px; vertical-align: -2px;
  border-radius: 50%;
}

/* — stat cells — */
.stat-cell { padding: var(--space-4) 18px; }
.stat-value { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 34px; line-height: 1; }
.stat-label {
  font-size: 12px; margin-top: 6px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* — the account screen — */
.profile-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 20px;
  margin: var(--space-3) 0 32px;
}
.profile-avatar {
  width: 72px; height: 72px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-accent); color: var(--color-bg);
  font-size: 24px; font-weight: 700;
}
.profile-identity { min-width: 0; flex: 1; }
/* An email address is one unbroken token. Someone who has not set a display
   name has one here at 42px, and without this it runs straight out of the
   container and gives the whole page a horizontal scrollbar. */
.profile-identity h1 {
  font-size: 42px; margin: 0;
  overflow-wrap: anywhere;
}
@media (max-width: 599px) { .profile-identity h1 { font-size: 30px; } }
.profile-identity p { margin: 0; font-size: 15px; overflow-wrap: anywhere; }
.profile-signout { margin-left: auto; }

/* Rows inside a panel, not free-standing cards: one subject with several facts
   about it, rather than several unrelated things. Separated by space alone —
   there is no rule to draw in this system. */
.settingrow {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 12px 0;
}
.settingrow-main { flex: 1; min-width: 0; }
.settingrow-title { font-weight: 600; font-size: 15px; }
.settingrow-meta {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
/* The one row that offers something rather than reporting it. */
.settingrow--offer {
  margin-top: var(--space-2);
  padding: 14px 18px;
  border-radius: calc(var(--radius-lg) * 0.85);
  background: var(--color-accent-100);
}
.settingrow--offer .settingrow-meta { color: var(--color-accent-800); }

/* — two-column split — */
.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 36px;
}
.split--wide { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
/* Panels carry their own padding, so the gap between them can be tighter than
   the one between bare columns of text. */
.split--cards { gap: var(--space-6); align-items: start; }
.measure-form { max-width: 900px; }

/* — a bordered panel — */
.panel {
  padding: var(--space-8);
  border-radius: calc(var(--radius-lg) * 1.15);
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
}
.panel--narrow { max-width: 640px; }
/* A table wants its own gutters, and it scrolls sideways inside the panel
   rather than making the page scroll. */
.panel--table { padding: 24px 28px; overflow-x: auto; }
/* What asks for a decision, rather than what merely happened. */
.panel--attention { background: var(--color-accent-100); box-shadow: none; }
/* People who are not here yet — the sage voice, so the distinction from the
   members table below it is carried by the ground and not only by a heading. */
.panel--pending { background: var(--color-accent-2-100); box-shadow: none; margin-bottom: var(--space-6); }

/* A member row: avatar, name over email, and whatever the row is badged with. */
.member-cell { display: flex; align-items: center; gap: 10px; }
.member-names { min-width: 0; }
.member-avatar {
  width: 32px; height: 32px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-accent-2); color: var(--color-bg);
  font-size: 12px; font-weight: 700;
}

.attention-rows { display: grid; gap: var(--space-2); }
.attention-row {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 14px 16px 14px 20px;
  border-radius: calc(var(--radius-lg) * 0.85);
  background: var(--color-neutral-100);
}

/* — active sessions — */
.sessions { max-width: 820px; }
.session-icon {
  width: 48px; height: 48px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-accent-100); color: var(--color-accent-700);
}

/* — backup codes — */
.codegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: var(--space-2);
}
.codechip {
  padding: 10px 14px;
  border-radius: 999px;
  background: var(--color-bg);
  font-family: var(--font-mono);
  font-weight: 600; font-size: 15px; line-height: 1;
  text-align: center;
}
.codegrid-actions { margin-top: var(--space-6); }

/* Guidance beside a form, on the second accent — not a warning. */
.panel--guidance { background: var(--color-accent-2-100); box-shadow: none; }
.panel--guidance .form-note { color: var(--color-accent-2-800); }
.plain-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.plain-list li { font-size: 15px; }
.field-help {
  font-size: 12px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* — audit log — */
.audit-lede { max-width: 540px; margin-bottom: 0; }
.pager {
  display: flex; align-items: center; gap: var(--space-3);
  margin-top: var(--space-6);
}
.pager-count {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* — usage meter — */
.meter { display: flex; align-items: center; gap: var(--space-2); }
.meter-track { width: 80px; height: 8px; border-radius: 999px; background: var(--color-neutral-300); display: block; overflow: hidden; }
/* Clamped, because usage past the limit produces a width above 100%. The bar
   stops at full and the colour change carries the overflow — a full bar and an
   overflowing one must not look the same. */
.meter-fill { display: block; height: 8px; max-width: 100%; background: var(--color-text); }
.meter-fill--over { background: var(--color-danger); }

/* — auth column — */
/* The sign-in screen is two columns on a wide window: the form on the left,
   and an accent panel on the right that exists to give the page a ground and a
   shape. Below the breakpoint the panel is removed rather than stacked — it
   carries one sentence and three circles, and 520px of decoration above the
   fold on a phone is worse than no decoration at all. */
/* An explicit breakpoint rather than auto-fit. auto-fit decides when to wrap
   from the space it is given, which the media query hiding the panel cannot
   see — so between the two there was a band where the grid had already dropped
   to one column and the panel was still being drawn, stacking 520px of pure
   decoration under the form. One number now governs both. */
.auth-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
  align-items: center;
  min-height: calc(100vh - 260px);
}
@media (min-width: 840px) {
  .auth-split { grid-template-columns: minmax(0, 400px) 1fr; }
}
.auth-panel {
  position: relative; overflow: hidden;
  min-height: 520px;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: var(--space-8);
  border-radius: calc(var(--radius-lg) * 1.45);
  background: var(--color-accent);
  color: var(--color-bg);
}
.auth-panel-line {
  position: relative; margin: 0;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 36px; line-height: 1.12;
  max-width: 380px;
  text-wrap: pretty;
}
.auth-blob { position: absolute; border-radius: 50%; }
.auth-blob--1 { width: 360px; height: 360px; background: var(--color-accent-400); top: -120px; right: -100px; }
.auth-blob--2 { width: 200px; height: 200px; background: var(--color-accent-2-400); top: 140px; right: 150px; }
.auth-blob--3 { width: 90px; height: 90px; background: var(--color-accent-200); top: 60px; left: 56px; }
@media (max-width: 839px) { .auth-panel { display: none; } }

.auth-submit { width: 100%; min-height: 50px; font-size: 16px; margin-top: 6px; }

/* A checkbox and its label read as one control, so they sit on one line —
   .field stacks a label above its input, which is right for everything else on
   these forms and wrong for this. */
.check { display: flex; align-items: center; gap: var(--space-2); font-size: 14px; }
.check input { width: auto; min-height: 0; flex: none; accent-color: var(--color-accent); }
.check label { cursor: pointer; }

/* Django renders errors as <ul class="errorlist">; nothing else styles them. */
.errorlist {
  list-style: none; margin: 0 0 var(--space-2); padding: 10px var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-danger-100); color: var(--color-danger-800);
  font-size: 13px;
}
.errorlist li + li { margin-top: var(--space-1); }

.auth-column { max-width: 400px; padding-top: var(--space-6); }
.auth-column h1 { font-size: 46px; margin: 0 0 10px; }
.auth-column .card-kicker + h1 { margin-top: 6px; }
.auth-mark { width: 52px; height: 52px; padding: 11px 14px; margin-bottom: 32px; border-radius: var(--radius-md); }
.auth-lede {
  margin: 0 0 26px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.btn-wide { width: 100%; justify-content: flex-start; padding: 13px 22px; }

/* — organisation picker and eligible roles — */
.picker { max-width: 760px; }
.picker-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 22px; line-height: 1.15;
}
/* The organisation's initial on its own colour — the one place a customer's
   colour appears at full strength, since here the whole point is telling two
   organisations apart at a glance. */
.picker-initial {
  width: 52px; height: 52px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 22px; line-height: 1;
}
.picker-enter { padding-inline: 22px; }
.eligible-rows { max-width: 820px; }

/* The design's "← Account and security" return link. A plain anchor rather than
   a button: it goes back to a page, it does not perform anything. */
.backlink {
  display: inline-block;
  margin-bottom: var(--space-2);
  font-size: 14px; font-weight: 600;
  text-decoration: none;
}
.backlink:hover { text-decoration: underline; }
.picker-row, .eligible-row { align-items: center; gap: var(--space-4); }
.page-title--tight { margin-bottom: var(--space-2); }
.step-tag { font-size: 12px; font-weight: 600; }
.auth-column--centred h1 { margin-top: var(--space-4); }
.picker-row > form, .eligible-action { margin-left: auto; }
.eligible-role { min-width: 240px; }
.eligible-action { min-width: 260px; }
.activate-form .field { margin-bottom: var(--space-2); }
.activate-form textarea.input { min-height: 56px; }

/* — get help — */
.contacts-grid { margin-bottom: var(--space-8); }
.contact { display: flex; gap: var(--space-4); }
.contact-body { min-width: 0; }
.contact-avatar {
  width: 56px; height: 56px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-accent-2); color: var(--color-bg);
  font-weight: 700; font-size: 15px;
}
/* Nilsaro's own support entry, on the brand navy the mark is drawn for. */
.contact-avatar--platform { background: var(--color-brand-navy); }
.contact-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 22px; line-height: 1.2; margin: 10px 0 2px;
}
.contact-role { margin-bottom: var(--space-3); }
.hr--tight { margin: 14px 0; }

/* The report block: explanation left, the thing to copy right. */
.report {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--space-8);
  align-items: start;
  padding: 36px;
  border-radius: calc(var(--radius-lg) * 1.45);
  background: var(--color-accent-100);
}
.report-head { font-size: 30px; margin: 0 0 var(--space-2); }
.report-lede { font-size: 15px; margin: 0 0 20px; color: var(--color-neutral-800); }
.report-send { padding-inline: 22px; }
.report .codeblock { background: var(--color-neutral-100); }

/* — notifications — */
.notifications { max-width: 860px; }

/* An empty state with a ground, so it does not read as a row that failed. */
.callout {
  padding: 40px;
  border-radius: calc(var(--radius-lg) * 1.15);
  background: var(--color-accent-2-100);
  max-width: 860px;
}
.callout--calm { background: var(--color-accent-2-100); }
.callout-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 24px; line-height: 1.15;
}
.callout p { margin: 6px 0 0; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.refline {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-bottom: 14px;
}

.page-title { font-size: 46px; margin: 0 0 28px; }
.page-head--tight { margin-bottom: var(--space-2); }
.listrow-link { color: var(--color-text); text-decoration: none; }
.listrow-link:hover { color: var(--color-accent-700); }
.auth-alt { font-size: 13px; margin: 0; }

/* — code / reference blocks — */
.refcode { font-family: var(--font-mono); font-weight: 600; font-size: 15px; line-height: 1; }
.codeblock {
  margin: 0 0 var(--space-4);
  padding: 20px 22px;
  border-radius: var(--radius-lg);
  background: var(--color-neutral-100);
  font-family: var(--font-mono);
  font-size: 13px; line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.form-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.stack-sm > * + * { margin-top: var(--space-3); }
.contact-lines { font-size: 13px; display: grid; gap: var(--space-1); }
.numeric-input { font-size: 20px; letter-spacing: 0.24em; min-height: 46px; }
.text-right { text-align: right; }
.nowrap { white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════════════════
   3. Compatibility — screens not part of the portal redesign
   ══════════════════════════════════════════════════════════════════════════ */

/* base.html is rendered by roughly fifty templates. The redesign covers the
   portal's own screens; password reset, API tokens, OU and role forms, landing
   editors and the assisted-creation flow keep their markup and are carried here
   so none of them renders unstyled. These are translations of main.css onto
   Organic tokens, not new design work — when one of those screens is rebuilt,
   delete its entry.

   They are rounded and elevated to match the redesign rather than left on
   Modernist's squared edges: a screen that keeps its old layout should still
   look like it belongs to the same product as the one next to it. */

.auth-card { max-width: 400px; padding-top: var(--space-6); }
.auth-card h1 { font-size: 38px; }

.sub-nav {
  display: inline-flex; flex-wrap: wrap; gap: 4px;
  margin-bottom: var(--space-6);
  padding: 5px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
}
.sub-nav a {
  color: var(--color-text); text-decoration: none;
  font-weight: 600; font-size: 14px; line-height: 1;
  padding: 9px 18px;
  border-radius: 999px;
  transition: background 0.15s;
}
.sub-nav a:hover { background: var(--color-accent-200); color: var(--color-text); }
.sub-nav a.nav-link-active { background: var(--color-accent-200); color: var(--color-text); }

/* Gapped and elevated, matching .cell-grid — the ring both used is gone. */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--space-3);
  margin: 0 0 var(--space-6);
}
.stat-card {
  background: var(--color-neutral-100);
  padding: 22px 24px;
  border-radius: calc(var(--radius-lg) * 1.0);
  box-shadow: var(--shadow-sm);
}
.stat-card strong { display: block; font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 34px; line-height: 1; }
.stat-card span { font-size: 12px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }

.launcher-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.launcher-tile {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--space-6);
  border-radius: calc(var(--radius-lg) * 1.15);
  background: var(--color-neutral-100);
  text-decoration: none; color: var(--color-text);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
a.launcher-tile:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  color: var(--color-text);
}
.launcher-tile__label { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 20px; line-height: 1.15; }
.launcher-tile__product,
.launcher-tile__description,
.launcher-tile__external { font-size: 13px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.launcher-tile--disabled { opacity: 0.55; cursor: default; }
.launcher-tile--disabled:hover {
  transform: none;
  box-shadow: var(--shadow-sm);
}
.launcher-tile__status {
  align-self: flex-start;
  font-size: 11px; letter-spacing: 0.02em;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--color-neutral-300);
  background: var(--color-neutral-200); color: var(--color-neutral-800);
}

.organisation-grid,
.tenant-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
}

.status-badge {
  display: inline-flex; align-items: center;
  font-size: 11px; letter-spacing: 0.02em;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.status-badge--neutral { background: var(--color-neutral-200); border-color: var(--color-neutral-300); color: var(--color-neutral-800); }
.status-badge--success { background: var(--color-accent-2-200); border-color: var(--color-accent-2-300); color: var(--color-accent-2-800); }
.status-badge--info { background: var(--color-accent-200); border-color: var(--color-accent-300); color: var(--color-accent-800); }
.status-badge--warning { background: var(--color-warning-200); border-color: var(--color-warning-300); color: var(--color-warning-800); }
.status-badge--danger { background: var(--color-danger-200); border-color: var(--color-danger-300); color: var(--color-danger-800); }

/* No rule under it: the tint is what marks the band, and Organic separates
   with ground and space rather than with strokes. */
.context-banner {
  padding: 11px 0;
  font-size: 13px;
}
.context-banner--platform { background: var(--color-accent-2-100); color: var(--color-accent-2-800); }
.context-banner--organisation_admin { background: var(--color-accent-100); color: var(--color-accent-800); }
.context-banner--support { background: var(--color-warning-100); color: var(--color-warning-800); }
.context-banner--assisted { background: var(--color-danger-100); color: var(--color-danger-800); font-weight: 600; }

.context-pill {
  display: inline-flex; align-items: center;
  padding: 3px 10px; font-size: 11px; font-weight: 600;
  border-radius: 999px;
  border: 1px solid transparent;
}
.context-pill--organisation,
.context-pill--tenant { background: var(--color-accent-200); border-color: var(--color-accent-300); color: var(--color-accent-800); }
.context-pill--support { background: var(--color-warning-200); border-color: var(--color-warning-300); color: var(--color-warning-800); }
.context-pill--user { background: var(--color-neutral-200); border-color: var(--color-neutral-300); color: var(--color-neutral-800); }

.admin-help {
  background: var(--color-accent-100);
  color: var(--color-accent-900);
  padding: 18px 24px;
  border-radius: var(--radius-lg);
  margin: 0 0 var(--space-4);
  font-size: 14px;
}
.notice { background: var(--color-warning-100); color: var(--color-warning-800); padding: var(--space-3) var(--space-6); border-radius: var(--radius-lg); font-size: 14px; }
.danger-zone { border: 1px solid var(--color-danger-300); background: var(--color-danger-100); padding: var(--space-6); border-radius: var(--radius-lg); margin-top: var(--space-4); }
.empty-state { color: color-mix(in srgb, var(--color-text) 55%, transparent); padding: var(--space-4) 0; }
.empty-state p { margin: 0 0 var(--space-2); }

.detail-list { margin: 0; }
.detail-list dt { font-weight: 600; margin-top: var(--space-3); }
.detail-list dt:first-child { margin-top: 0; }
.detail-list dd { margin: var(--space-1) 0 0; }

.filter-form { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-end; }
.filter-form label { font-size: 12px; }
.form-input { width: 100%; }
.form-note, .help-text { font-size: 12px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.form-errors { color: var(--color-danger-800); font-size: 13px; }
.form-stack > p { margin: 0 0 var(--space-3); }

.foundation-list { list-style: disc; padding-left: var(--space-6); }
.shortcut-list { list-style: none; padding: 0; margin: 0; }
.shortcut-list li { margin-bottom: 6px; }
.notification-list { list-style: none; padding: 0; margin: 0; }
.notification-list li { padding: var(--space-2) 0; border-bottom: 1px solid var(--color-divider); }
.notification-unread { font-weight: 600; }

.token-secret { word-break: break-all; background: var(--color-surface); padding: var(--space-3); font-family: var(--font-mono); font-size: 13px; }
.qr-code { display: block; margin: var(--space-4) 0; }
.muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.btn-sm { padding: 5px 10px; font-size: 13px; }
.btn-link { background: none; border: 0; padding: 0; color: var(--color-accent-700); cursor: pointer; font: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* Product module links in the header. Set apart from the surrounding nav by
   weight rather than a rule — they are the same kind of destination. */
.product-nav { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 22px; }
.product-nav-link { font-weight: 600; }

/* Fallback tables. Screens outside the redesign use bare <table>; the redesign's
   own tables carry .table from organic.css. */
main table { width: 100%; border-collapse: collapse; font-size: 14px; }
main th, main td { text-align: left; padding: var(--space-2); border-bottom: 1px solid var(--color-divider); vertical-align: top; }
main th {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  border-bottom: 1px solid var(--color-divider);
}

/* — small odds and ends the redesigned screens introduce — */
.filter-form { display: flex; align-items: center; gap: var(--space-2); }
.filter-label {
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.filter-form .input { width: auto; min-width: 150px; }
.seats-actions { margin-top: var(--space-4); }
/* The badge on a one-off confirmation screen — a mail icon, a tick, a key. */
.auth-badge {
  width: 64px; height: 64px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--color-accent-2); color: var(--color-neutral-100);
  margin: 28px 0 20px;
}

/* The erase screen. Its warnings used to carry .alert / .alert-danger, which
   no stylesheet at this origin defines — so the one irreversible action in the
   product rendered its warnings as body text. */
.notice--block { display: block; margin-bottom: var(--space-6); }
.notice--block p { margin: 0 0 var(--space-2); }
.notice--block .plain-list { margin-bottom: var(--space-2); }
.danger-zone--confirm { max-width: 640px; }
.danger-zone p { margin-top: 0; }
.profile-avatar--danger { background: var(--color-danger); }
.standing { margin-bottom: var(--space-6); }
.panel--spaced { margin-top: var(--space-6); }
