/* ============================================================================
   TLN design system — Technology Leaders Network
   ----------------------------------------------------------------------------
   The fourth look this file has carried (glass -> flat replica -> warm
   monochrome -> this). Taken from the TLN brand artwork and its app mockup:
   a navy top bar carrying the reversed logo, a cool light ground, white cards,
   and one blue for every "do this" and "you are here".

   Sampled with PIL, not chosen by eye:
     logo navy     #0b1f3a   letters, ink, the top bar
     logo blue     #1769e0   the L, primary actions, active states
     logo cyan     #22d3ee   network glyph only
     logo amber    #f5b942   network glyph only
     logo slate    #64748b   the divider rule; also faint text (4.7:1 on white)
     ground        #f3f5f9   page background in the mockup
     active nav    #ecf2fd   tint behind the current sidebar item

   Cyan and amber belong to the mark. They are not UI colours: a third and
   fourth accent on controls would compete with the one blue that means "act".

   Structure: Tailwind still does layout and spacing; every surface, control and
   type role comes from here. The whole look is swappable from this one file.
   ========================================================================= */

:root {
  /* ── Ground and surfaces ─────────────────────────────────────────────── */
  --ctl-ground:       #f3f5f9;
  --ctl-surface:      #ffffff;
  --ctl-sunk:         #f1f4f9;
  --ctl-tint:         #ecf2fd;   /* active nav, selected rows */

  /* ── Lines ───────────────────────────────────────────────────────────── */
  --ctl-border:       #e2e7ef;
  --ctl-border-soft:  #edf0f5;
  --ctl-rule:         #f1f3f7;
  --ctl-divider:      #eceff4;

  /* ── Ink: the logo's navy, stepped down ───────────────────────────────── */
  --ctl-ink:          #0b1f3a;
  --ctl-body:         #2f3d52;
  --ctl-muted:        #475569;
  --ctl-faint:        #64748b;   /* the logo's own rule colour; 4.7:1 on white */

  /* ── Action: the logo's blue ─────────────────────────────────────────── */
  --ctl-action:       #1769e0;
  --ctl-action-hover: #1257c0;
  --ctl-blue:         #1769e0;
  --ctl-blue-hover:   #1257c0;
  --ctl-blue-soft:    #e8f1fd;   /* selected pill, prompt chips */

  /* ── The bar ─────────────────────────────────────────────────────────── */
  --ctl-bar:          #0b1f3a;
  --ctl-bar-ink:      #ffffff;
  --ctl-bar-muted:    rgba(255,255,255,0.72);
  --ctl-bar-hover:    rgba(255,255,255,0.09);
  --ctl-bar-line:     rgba(255,255,255,0.14);

  /* Brand mark colours, for the logo partial and nothing else. */
  --tln-navy:         #0b1f3a;
  --tln-blue:         #1769e0;
  --tln-cyan:         #22d3ee;
  --tln-amber:        #f5b942;
  --tln-slate:        #64748b;

  /* Unread markers. */
  --ctl-red:          #e5484d;
  --ctl-accent:       #1769e0;

  /* Legacy token names kept alive because inline `style=` uses in the
     templates reference them. Remapping here rather than editing the markup is
     the whole reason a restyle costs one file. */
  --ctl-frame:        #0b1f3a;
  --ctl-navy:         #0b1f3a;
  --ctl-violet:       #1769e0;
  --ctl-purple:       #1769e0;
  --ctl-lavender:     #e8f1fd;
  --ctl-chip:         #f1f4f9;
  --ctl-sidebar:      #ffffff;

  /* ── Semantic ────────────────────────────────────────────────────────── */
  --ctl-good:         #15803d;
  --ctl-good-bg:      #ecfdf3;
  --ctl-warn:         #8a5410;
  --ctl-warn-bg:      #fdf6e7;
  --ctl-bad:          #b42318;
  --ctl-bad-bg:       #fef0ef;
  --ctl-info:         #1769e0;
  --ctl-info-bg:      #eef4fe;

  /* ── Geometry ────────────────────────────────────────────────────────── */
  --ctl-radius:       12px;
  --ctl-radius-sm:    10px;
  --ctl-radius-xs:    8px;
  --ctl-topbar-h:     64px;
  --ctl-sidebar-w:    264px;

  /* Cards sit on the ground with a whisper of lift, as in the mockup;
     overlays get a real shadow. */
  --ctl-shadow-card:  0 1px 2px rgba(11,31,58,0.04);
  --ctl-shadow-pop:   0 1px 2px rgba(11,31,58,0.06),
                      0 12px 28px -8px rgba(11,31,58,0.18);

  --ctl-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
              Roboto, Helvetica, Arial, sans-serif;
}

/* ── The logo (_partials/wordmark.html) ──────────────────────────────────── */
.tln-logo {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  --tln-letter: var(--tln-navy);
  --tln-accent: var(--tln-blue);
  --tln-line:   var(--tln-navy);
  color: var(--tln-navy);
}
.tln-logo-dark {
  --tln-letter: #ffffff;
  --tln-accent: #3d8bff;          /* the L, lifted so it holds on navy */
  --tln-line:   #ffffff;
  color: #ffffff;
}
.tln-mark { height: 30px; width: auto; flex-shrink: 0; display: block; }
.tln-logo-rule {
  width: 1.5px; align-self: stretch; margin: 3px 0;
  background: var(--tln-slate);
}
.tln-logo-dark .tln-logo-rule { background: rgba(255,255,255,0.35); }
.tln-logo-name {
  max-width: 8.9em;               /* "Technology / Leaders Network", as drawn */
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.005em;
}
.tln-logo-lg { gap: 18px; }
.tln-logo-lg .tln-mark { height: 46px; }
.tln-logo-lg .tln-logo-name { font-size: 17px; }

/* ── Base ─────────────────────────────────────────────────────────────────── */
/* Light only, to match the meta tag in _partials/head.html. Without it a
   dark-mode browser gives unclassed form controls a dark UA fill under our
   navy text — typed input becomes invisible. */
:root { color-scheme: light; }
html { background: var(--ctl-ground); }

body {
  font-family: var(--ctl-font);
  font-size: 16px;
  line-height: 1.7;              /* sampled: 16/27.2 */
  color: var(--ctl-body);
  background: var(--ctl-ground);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* No-op shims kept so templates need no sweep. Do not build on these. */
.ctl-ground { display: none; }
.ctl-sheen  { position: relative; }
.ctl-rise   { animation: none; }
.ctl-glass, .ctl-glass-dark { background: var(--ctl-surface); }

/* ── App frame ────────────────────────────────────────────────────────────── */
/* Navy bar across the top, white sidebar under it, cool ground behind the
   content so white cards read as raised. */
.ctl-app {
  display: flex;
  align-items: stretch;
  min-height: calc(100vh - var(--ctl-topbar-h));
}

.ctl-topbar {
  height: var(--ctl-topbar-h);
  background: var(--ctl-bar);
  color: var(--ctl-bar-ink);
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 1.25rem;
}

.ctl-logo-tile {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding: 0 0.25rem;
}

/* Search: a translucent field on the navy bar. */
.ctl-topbar-search {
  width: 100%;
  height: 40px;
  font-size: 14px;
  color: var(--ctl-bar-ink);
  background: rgba(255,255,255,0.07);
  border: 1px solid var(--ctl-bar-line);
  border-radius: var(--ctl-radius-sm);
  padding: 0 0.875rem 0 2.375rem;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.ctl-topbar-search::placeholder { color: var(--ctl-bar-muted); }
.ctl-topbar-search:focus {
  outline: none;
  background: rgba(255,255,255,0.12);
  border-color: rgba(255,255,255,0.35);
  box-shadow: 0 0 0 3px rgba(61,139,255,0.35);
}
.ctl-topbar-search-icon { color: var(--ctl-bar-muted); }

.ctl-topbar-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 40px; height: 40px;
  border-radius: var(--ctl-radius-sm);
  color: var(--ctl-bar-muted);
  transition: background 140ms ease, color 140ms ease;
}
.ctl-topbar-icon:hover { background: var(--ctl-bar-hover); color: var(--ctl-bar-ink); }

/* The account button on the bar. */
.ctl-topbar-profile {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.25rem 0.5rem 0.25rem 0.25rem;
  border-radius: var(--ctl-radius-sm);
  color: var(--ctl-bar-ink);
  transition: background 140ms ease;
}
.ctl-topbar-profile:hover { background: var(--ctl-bar-hover); }
.ctl-topbar-profile .ctl-avatar { border-color: rgba(255,255,255,0.25); }
.ctl-topbar-profile-sub { color: var(--ctl-bar-muted); }
.ctl-topbar .ctl-eyebrow { color: var(--ctl-bar-muted); }

/* Unread marker: the accent, used at the smallest possible size. */
.ctl-topbar-badge {
  position: absolute;
  top: 4px; right: 4px;
  min-width: 17px; height: 17px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--ctl-red);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  line-height: 13px;
  text-align: center;
  border: 2px solid var(--ctl-bar);
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */
.ctl-sidebar {
  width: var(--ctl-sidebar-w);
  flex-shrink: 0;
  background: var(--ctl-surface);
  border-right: 1px solid var(--ctl-border);
  padding: 1.25rem 0.75rem;
}
.ctl-sidebar-inner {
  position: sticky;
  top: calc(var(--ctl-topbar-h) + 1.25rem);
  max-height: calc(100vh - var(--ctl-topbar-h) - 2.5rem);
  overflow-y: auto;
}

.ctl-main {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--ctl-ground);
  padding: 2rem 2rem 4rem;
}

/* ── Right rail: Trending Topics ─────────────────────────────────────────────
   The third column of the shell. Same ground as .ctl-main so its white cards
   read as part of the content, not as more chrome; sticky like the sidebar. It
   leaves below 1280px, where three columns would squeeze the content column
   under the width the feed's cards were designed for — /topics stays
   reachable from the profile menu there. */
.ctl-rail {
  width: 300px;
  flex-shrink: 0;
  background: var(--ctl-ground);
  padding: 2rem 1.25rem 4rem 0;
}
.ctl-rail-inner {
  position: sticky;
  top: calc(var(--ctl-topbar-h) + 2rem);
  max-height: calc(100vh - var(--ctl-topbar-h) - 3rem);
  overflow-y: auto;
}
@media (max-width: 1279px) { .ctl-rail { display: none; } }

/* One topic row: a whole-row button (pick) or link (already picked). */
.ctl-topic-row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.4rem 0.5rem;
  margin: 0 -0.5rem;
  border-radius: var(--ctl-radius-sm);
  font-size: 13px;
  text-align: left;
  color: var(--ctl-body);
  transition: background 140ms ease;
}
.ctl-topic-row:hover { background: var(--ctl-sunk); color: var(--ctl-ink); }
.ctl-topic-rank { width: 1.25rem; flex-shrink: 0; font-size: 11px; color: var(--ctl-faint); }
.ctl-topic-count { margin-left: auto; flex-shrink: 0; font-size: 11px; color: var(--ctl-faint); }

/* A selectable topic chip — the welcome picker and "Your topics". The checkbox
   is visually hidden but stays focusable, so the picker works by keyboard. */
.ctl-topic-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border-radius: 999px;
  border: 1px solid var(--ctl-border);
  background: var(--ctl-surface);
  font-size: 13px;
  color: var(--ctl-body);
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.ctl-topic-chip:hover { border-color: #cfd8e5; background: var(--ctl-sunk); color: var(--ctl-ink); }
/* Picked = the active pill's treatment, so "selected" means one thing here. */
.ctl-topic-chip-on, .ctl-topic-chip-on:hover,
.ctl-topic-chip:has(input:checked) {
  background: var(--ctl-blue-soft);
  border-color: var(--ctl-blue);
  color: var(--ctl-blue);
  font-weight: 500;
}
.ctl-topic-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ctl-topic-chip:has(input:focus-visible) { outline: 2px solid var(--ctl-blue); outline-offset: 2px; }

/* Group headings: quiet, letterspaced. */
.ctl-sidebar-group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0.375rem 0.75rem;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ctl-faint);
  transition: color 140ms ease;
}
.ctl-sidebar-group:hover { color: var(--ctl-muted); }

.ctl-sidebar-divider {
  height: 1px;
  background: var(--ctl-divider);
  border: 0;
  margin: 1rem 0.75rem;
}

/* ── Nav ──────────────────────────────────────────────────────────────────── */
.ctl-nav-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5625rem 0.75rem;
  border-radius: var(--ctl-radius-xs);
  font-size: 14.5px;
  font-weight: 450;
  color: var(--ctl-muted);
  transition: background 140ms ease, color 140ms ease;
}
.ctl-nav-link svg { color: var(--ctl-faint); transition: color 140ms ease; }
.ctl-nav-link:hover { background: var(--ctl-sunk); color: var(--ctl-ink); }
.ctl-nav-link:hover svg { color: var(--ctl-ink); }

/* Active: blue tint, blue type, and a blue bar on the leading edge — the
   mockup's "you are here". */
.ctl-nav-link-active,
.ctl-nav-link-active:hover {
  background: var(--ctl-tint);
  color: var(--ctl-blue);
  font-weight: 600;
}
.ctl-nav-link-active svg, .ctl-nav-link-active:hover svg { color: var(--ctl-blue); }
.ctl-nav-link-active::before {
  content: "";
  position: absolute;
  left: 0; top: 7px; bottom: 7px;     /* inside the pill: the sidebar's
                                         scroll box clips anything outside */
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--ctl-blue);
}

/* ── Cards ────────────────────────────────────────────────────────────────── */
.ctl-card {
  background: var(--ctl-surface);
  border: 1px solid var(--ctl-border);
  border-radius: var(--ctl-radius);
  box-shadow: var(--ctl-shadow-card);
}
.ctl-card-interactive { transition: border-color 160ms ease, box-shadow 160ms ease; }
.ctl-card-interactive:hover { border-color: #c9d6ea; box-shadow: 0 4px 14px -6px rgba(11,31,58,0.12); }

/* Overlays: the one place the reference uses elevation. */
.ctl-raised {
  background: var(--ctl-surface);
  border: 1px solid var(--ctl-border);
  border-radius: var(--ctl-radius);
  box-shadow: var(--ctl-shadow-pop);
}

.ctl-sunk { background: var(--ctl-sunk); border-radius: var(--ctl-radius-sm); }

hr.ctl-rule-brass, .ctl-rule-brass {
  height: 1px; border: 0; background: var(--ctl-divider);
}

/* ── Typography ───────────────────────────────────────────────────────────── */
/* The single biggest change from the previous look: display type is LARGER and
   LIGHTER. The reference tops out at weight 600 and sets 64px display at 1.05
   line-height. The old look used 700/800 at small sizes, which reads busy. */
.ctl-display {
  font-family: var(--ctl-font);
  font-weight: 700;
  font-size: 32px;
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--ctl-ink);
  text-wrap: balance;
}

.ctl-eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ctl-faint);
}

.ctl-prose { max-width: 68ch; line-height: 1.7; color: var(--ctl-body); }
.ctl-prose p + p { margin-top: 1em; }
.ctl-num { font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.ctl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--ctl-font);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  padding: 0.6875rem 1.125rem;
  border-radius: var(--ctl-radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background 140ms ease, border-color 140ms ease,
              color 140ms ease, opacity 140ms ease;
}
.ctl-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.ctl-btn:focus-visible { outline: 2px solid var(--ctl-blue); outline-offset: 2px; }

/* Primary is the logo's blue. */
.ctl-btn-primary { background: var(--ctl-action); color: #fff; }
.ctl-btn-primary:hover { background: var(--ctl-action-hover); }

/* No violet in the brand — Create is simply the primary action. */
.ctl-btn-violet { background: var(--ctl-action); color: #fff; }
.ctl-btn-violet:hover { background: var(--ctl-action-hover); }

.ctl-btn-ghost, .ctl-btn-brass {
  background: var(--ctl-surface);
  color: var(--ctl-ink);
  border-color: var(--ctl-border);
}
.ctl-btn-ghost:hover, .ctl-btn-brass:hover {
  background: var(--ctl-sunk);
  border-color: #cfd8e5;
}

.ctl-btn-danger { background: var(--ctl-bad); color: #fff; }
.ctl-btn-danger:hover { background: #9a1f18; }

.ctl-btn-sm { padding: 0.4375rem 0.75rem; font-size: 13px; border-radius: var(--ctl-radius-xs); }

/* White pill on a dark field. */
.ctl-btn-on-blue { background: #fff; color: var(--ctl-ink); }
.ctl-btn-on-blue:hover { background: var(--ctl-sunk); }

/* ── Fields ───────────────────────────────────────────────────────────────── */
.ctl-input, .ctl-select, .ctl-textarea {
  width: 100%;
  font-family: var(--ctl-font);
  font-size: 14px;
  color: var(--ctl-ink);
  background: var(--ctl-surface);
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--ctl-border);
  border-radius: var(--ctl-radius-sm);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.ctl-input::placeholder, .ctl-textarea::placeholder { color: var(--ctl-faint); }
.ctl-input:focus, .ctl-select:focus, .ctl-textarea:focus {
  outline: none;
  border-color: var(--ctl-blue);
  box-shadow: 0 0 0 3px rgba(23,105,224,0.14);
}
.ctl-textarea { resize: vertical; line-height: 1.65; }
.ctl-select {
  appearance: none;
  padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%235c5f66' stroke-width='1.75' stroke-linecap='round'%3E%3Cpath d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.875rem center;
}
.ctl-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--ctl-muted);
  margin-bottom: 0.375rem;
}

/* ── Feed filter chips ────────────────────────────────────────────────────── */
/* Was a grey block; now a hairline pill, matching the reference's date picker
   and segmented controls. */
.ctl-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: var(--ctl-surface);
  border: 1px solid var(--ctl-border);
  border-radius: 999px;
  padding: 0.5rem 0.875rem;
  font-size: 12px;
  color: var(--ctl-faint);
  cursor: pointer;
  transition: border-color 140ms ease;
}
.ctl-filter-chip:hover { border-color: #cfd8e5; }
.ctl-filter-chip select {
  appearance: none;
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--ctl-ink);
  text-transform: none;
  cursor: pointer;
  padding-right: 1.125rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' fill='none' stroke='%230b1f3a' stroke-width='1.75' stroke-linecap='round'%3E%3Cpath d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right center;
}
.ctl-filter-chip select:focus { outline: none; }

/* ── Filter pills ─────────────────────────────────────────────────────────── */
.ctl-pill {
  padding: 0.4375rem 0.9375rem;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 400;
  color: var(--ctl-body);
  background: var(--ctl-surface);
  border: 1px solid var(--ctl-border);
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.ctl-pill:hover { background: var(--ctl-sunk); border-color: #cfd8e5; }
/* Active is a blue outline on a blue wash, as the mockup's "All" pill is. */
.ctl-pill-active, .ctl-pill-active:hover {
  background: var(--ctl-blue-soft);
  border-color: var(--ctl-blue);
  color: var(--ctl-blue);
  font-weight: 600;
}

/* ── Tabs ─────────────────────────────────────────────────────────────────── */
.ctl-tab {
  padding: 0.625rem 0 0.875rem;
  font-size: 15px;
  font-weight: 400;
  color: var(--ctl-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: color 140ms ease, border-color 140ms ease;
}
.ctl-tab:hover { color: var(--ctl-ink); }
.ctl-tab-active, .ctl-tab-active:hover {
  color: var(--ctl-blue);
  font-weight: 600;
  border-bottom-color: var(--ctl-blue);
}

/* ── Chips ────────────────────────────────────────────────────────────────── */
.ctl-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 12px;
  font-weight: 500;
  padding: 0.25rem 0.5625rem;
  border-radius: 999px;             /* sampled: 100px pills */
  border: 1px solid transparent;
}
.ctl-chip-good { color: var(--ctl-good); background: var(--ctl-good-bg); }
.ctl-chip-warn { color: var(--ctl-warn); background: var(--ctl-warn-bg); }
.ctl-chip-bad  { color: var(--ctl-bad);  background: var(--ctl-bad-bg); }
.ctl-chip-info { color: var(--ctl-info); background: var(--ctl-info-bg); }
/* Provenance, not status. good/warn/bad are a scale about how a thing IS;
   this says where it CAME FROM, so it gets an outline instead of a fill and
   sits outside that scale — otherwise "Global" reads as a severity. */
.ctl-chip-global {
  color: var(--ctl-info);
  background: transparent;
  border-color: color-mix(in srgb, var(--ctl-info) 40%, transparent);
}
.ctl-chip-mute { color: var(--ctl-muted); background: var(--ctl-sunk); }

/* ── Avatars ──────────────────────────────────────────────────────────────── */
.ctl-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ctl-muted);
  background: var(--ctl-sunk);
  border: 1px solid var(--ctl-border);
}
.ctl-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ctl-avatar-brass { background: var(--ctl-sunk); color: var(--ctl-ink); }

.ctl-online {
  width: 8px; height: 8px;
  border-radius: 999px;
  background: #22a06b;
  box-shadow: 0 0 0 2px var(--ctl-surface);
}

/* ── The in-post prompt ───────────────────────────────────────────────────── */
/* The one high-emphasis surface: the brand blue, deepening toward navy. */
.ctl-prompt {
  background: linear-gradient(135deg, #1769e0 0%, #0f4fb0 100%);
  border-radius: var(--ctl-radius);
  padding: 2.5rem 2rem;
  text-align: center;
}
.ctl-prompt-title {
  color: #fff;
  font-size: 22px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.015em;
}

/* ── Tables ───────────────────────────────────────────────────────────────── */
.ctl-table { width: 100%; font-size: 14px; border-collapse: collapse; }
.ctl-table thead th, .ctl-thead th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ctl-faint);
  padding: 0.75rem 1.25rem;
  white-space: nowrap;
}
.ctl-table thead th, .ctl-thead {
  background: var(--ctl-sunk);
  border-bottom: 1px solid var(--ctl-border);
}
.ctl-table tbody td { padding: 0.8125rem 1.25rem; color: var(--ctl-body); }
.ctl-table tbody tr { border-top: 1px solid var(--ctl-divider); }
.ctl-table tbody tr:first-child { border-top: 0; }
.ctl-table tbody tr:hover { background: #f7f9fd; }

/* ── Utility ──────────────────────────────────────────────────────────────── */
.ctl-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.ctl-scroll::-webkit-scrollbar-track { background: transparent; }
.ctl-scroll::-webkit-scrollbar-thumb { background: #d5dce7; border-radius: 999px; }
.ctl-scroll::-webkit-scrollbar-thumb:hover { background: #bcc6d5; }

/* Native controls default to the browser's blue, which is the last bright accent
   left over from the previous look. accent-color aligns them with the palette
   without replacing them with divs — they keep full keyboard and AT behaviour. */
input[type="checkbox"], input[type="radio"] {
  accent-color: var(--ctl-blue);
  width: 15px;
  height: 15px;
}
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible {
  outline: 2px solid var(--ctl-blue);
  outline-offset: 2px;
}

[x-cloak] { display: none !important; }

/* ── Motion & loading ───────────────────────────────────────────────────────
   Three jobs, each small:
     1. Content ARRIVES rather than appears: cards rise 6px and fade in, lightly
        staggered, once per page load (and when HTMX inserts new ones).
     2. Waiting LOOKS like the thing being waited for: skeleton blocks with a
        shimmer, in the panels HTMX fills, behind images still downloading, and
        in the content column between a click and the next page.
     3. Every request is ACKNOWLEDGED within a frame: a 3px bar across the top.
   static/js/ui.js drives 2 and 3. The `prefers-reduced-motion` rule below this
   block collapses every duration, so skeletons stay but stop moving.

   The rise uses `animation-fill-mode: backwards`, NOT both/forwards: a
   transform left on a card after the animation would become the containing
   block for any position:fixed descendant (a dropdown, a modal) and pin it to
   the card instead of the viewport. */
@keyframes ctl-rise-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes ctl-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ctl-shimmer {
  from { background-position: 150% 0; }
  to   { background-position: -50% 0; }
}
@keyframes ctl-pop {
  0% { transform: scale(0.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); }
}

.ctl-page .ctl-card,
.ctl-page .ctl-tile,
.ctl-rail .ctl-card {
  animation: ctl-rise-in 380ms cubic-bezier(.2,.7,.2,1) backwards;
}
.ctl-page .ctl-card:nth-child(2), .ctl-page .ctl-tile:nth-child(2), .ctl-rail .ctl-card:nth-child(2) { animation-delay: 40ms; }
.ctl-page .ctl-card:nth-child(3), .ctl-page .ctl-tile:nth-child(3), .ctl-rail .ctl-card:nth-child(3) { animation-delay: 80ms; }
.ctl-page .ctl-card:nth-child(4), .ctl-page .ctl-tile:nth-child(4) { animation-delay: 120ms; }
.ctl-page .ctl-card:nth-child(5), .ctl-page .ctl-tile:nth-child(5) { animation-delay: 160ms; }
.ctl-page .ctl-card:nth-child(n+6), .ctl-page .ctl-tile:nth-child(n+6) { animation-delay: 200ms; }
/* Cards nested in cards (a comment inside a post) arrive with their parent. */
.ctl-page .ctl-card .ctl-card { animation: none; }

/* Page heading and flash slide in with the content, not after it. */
.ctl-page > * > h1:first-child,
.ctl-page .ctl-display { animation: ctl-fade-in 300ms ease backwards; }
#ctl-flash { animation: ctl-rise-in 300ms ease backwards; }

/* Anything HTMX swaps in: a new chat line, a notification list, a reaction. */
.htmx-added { animation: ctl-rise-in 260ms ease backwards; }
.ctl-topbar-badge { animation: ctl-pop 360ms cubic-bezier(.3,1.6,.5,1) backwards; }

/* Micro-interactions. Press feels physical; cards lift on hover. */
.ctl-btn:not(:disabled):active { transform: translateY(1px) scale(0.98); }
.ctl-btn { transition: background 140ms ease, border-color 140ms ease, color 140ms ease,
                       opacity 140ms ease, transform 90ms ease, box-shadow 140ms ease; }
.ctl-btn-primary:not(:disabled):hover { box-shadow: 0 4px 12px -4px rgba(23,105,224,0.45); }
.ctl-card-interactive:hover, a.ctl-tile-link:hover { transform: translateY(-2px); }
a.ctl-tile-link { transition: border-color 160ms ease, transform 160ms ease, box-shadow 160ms ease; }
a.ctl-tile-link:hover { box-shadow: 0 8px 20px -10px rgba(11,31,58,0.22); }
.ctl-nav-link svg { transition: color 140ms ease, transform 160ms ease; }
.ctl-nav-link:hover svg { transform: translateX(1px) scale(1.06); }
.ctl-topbar-icon svg { transition: transform 160ms ease; }
.ctl-topbar-icon:hover svg { transform: scale(1.08); }
.ctl-avatar img { animation: ctl-fade-in 240ms ease backwards; }

/* ── Skeletons ─────────────────────────────────────────────────────────── */
.ctl-skel {
  display: block;
  border-radius: 6px;
  background: linear-gradient(90deg, #eef1f6 0%, #e3e8f0 20%, #eef1f6 40%, #eef1f6 100%);
  background-size: 200% 100%;
  animation: ctl-shimmer 1.3s linear infinite;
}
.ctl-skel-line   { height: 10px; }
.ctl-skel-title  { height: 22px; border-radius: 8px; }
.ctl-skel-circle { border-radius: 999px; flex-shrink: 0; }
.ctl-skel-block  { border-radius: var(--ctl-radius-sm); }

/* An image still on its way shimmers in its own box, then fades in. */
img.ctl-img-loaded { animation: ctl-fade-in 260ms ease backwards; }
.ctl-img-wait {
  background: linear-gradient(90deg, #eef1f6 0%, #e3e8f0 20%, #eef1f6 40%, #eef1f6 100%) !important;
  background-size: 200% 100% !important;
  animation: ctl-shimmer 1.3s linear infinite;
}

/* Between a click and the next page: the content column swaps to a skeleton.
   ui.js sets .is-navigating on <body> after a short delay, so a fast page
   never flashes one. */
.ctl-page-skeleton { display: none; }
body.is-navigating .ctl-page { display: none; }
body.is-navigating .ctl-page-skeleton { display: block; animation: ctl-fade-in 160ms ease; }

/* ── Progress bar ──────────────────────────────────────────────────────────
   Blue into the glyph's cyan: the one place a logo colour leaves the logo,
   because the bar is a brand flourish, not a control. */
#ctl-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 100;
  pointer-events: none;
  transform-origin: 0 50%;
  transform: scaleX(0);
  opacity: 0;
  background: linear-gradient(90deg, #1769e0, #22d3ee);
  box-shadow: 0 0 8px rgba(34,211,238,0.6);
}
#ctl-progress.is-running {
  opacity: 1;
  transform: scaleX(0.85);
  transition: transform 8s cubic-bezier(.1,.7,.2,1), opacity 120ms ease;
}
#ctl-progress.is-done {
  opacity: 0;
  transform: scaleX(1);
  transition: transform 180ms ease, opacity 260ms ease 180ms;
}
.ctl-overflow-x { overflow-x: auto; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (max-width: 640px) {
  .ctl-topbar { gap: 0.5rem; padding: 0 0.75rem; }
  .ctl-topbar .tln-logo-rule, .ctl-topbar .tln-logo-name { display: none; }
  .ctl-topbar .tln-mark { height: 24px; }
}

@media (max-width: 1024px) {
  .ctl-app { flex-direction: column; }
  .ctl-sidebar { width: 100%; border-right: 0; border-bottom: 1px solid var(--ctl-border); }
  .ctl-sidebar-inner { position: static; max-height: none; }
  .ctl-main { padding: 1.25rem 1.25rem 3rem; }
}

/* ── Usage meters ─────────────────────────────────────────────────────────
   A budget bar. The FILL WIDTH is set inline because it is data, not styling;
   the colour never is — an inline background on a control beats the class and
   silently flattens it, which has already happened once in this file's history.
   State comes from the semantic tokens, so "over budget" reads the same here as
   everywhere else. */
.ctl-meter {
  height: 6px;
  border-radius: 999px;
  background: var(--ctl-sunk);
  overflow: hidden;
}
.ctl-meter-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--ctl-blue);
  transition: width .3s ease;
}
.ctl-meter-fill.is-warn { background: var(--ctl-warn); }
.ctl-usage-link { color: inherit; }
.ctl-usage-link.is-warn { color: var(--ctl-warn); }
.ctl-usage-link.is-over { color: var(--ctl-bad); font-weight: 600; }
.ctl-meter-fill.is-over { background: var(--ctl-bad); }

/* Figure + label pair sitting above a meter. */
.ctl-meter-value { font-size: 20px; font-weight: 600; color: var(--ctl-ink);
                   font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.ctl-meter-of    { font-size: 13px; font-weight: 500; color: var(--ctl-faint);
                   font-variant-numeric: tabular-nums; }

/* ── Risk dashboard components ────────────────────────────────────────────
   Built on the existing tokens rather than a second palette, so /ciso does not
   read as a different product from the rest of CTL. The reference look is flat,
   so these carry a hairline and no shadow like every other surface here. */

/* KPI card: label, figure, signed delta, sparkline. */
.ctl-kpi { display: flex; flex-direction: column; gap: 6px; }
.ctl-kpi-label { font-size: 12px; font-weight: 500; color: var(--ctl-faint);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ctl-kpi-value { font-size: 25px; font-weight: 700; letter-spacing: -.035em;
                 line-height: 1.05; color: var(--ctl-ink);
                 font-variant-numeric: tabular-nums; }
.ctl-kpi-foot { display: flex; align-items: flex-end; justify-content: space-between;
                gap: 10px; }
.ctl-kpi-note { font-size: 11px; color: var(--ctl-faint); }
.ctl-kpi-note.is-alarm { color: var(--ctl-bad); font-weight: 500; }

/* The delta is an arrow plus a number, and its colour follows the
   INTERPRETATION, not the sign: falling exposure and rising coverage are both
   good news with opposite signs. */
.ctl-delta { display: inline-flex; align-items: center; gap: 3px; font-size: 12px;
             font-weight: 600; white-space: nowrap;
             font-variant-numeric: tabular-nums; }
.ctl-delta.is-good { color: var(--ctl-good); }
.ctl-delta.is-bad  { color: var(--ctl-bad); }

/* Attention strip — the one block on the page that asks for action. */
.ctl-attention { background: var(--ctl-bad-bg); border: 1px solid var(--ctl-bad);
                 border-radius: var(--ctl-radius-sm); padding: 9px 13px; }
.ctl-attention-title { font-size: 12.5px; font-weight: 600; color: var(--ctl-bad); }
.ctl-attention-item { font-size: 12.5px; color: var(--ctl-body); }

/* Posture gauge, sized for the page header. */
.ctl-gauge { display: flex; align-items: center; gap: 11px;
             background: var(--ctl-sunk); border: 1px solid var(--ctl-border);
             border-radius: var(--ctl-radius-sm); padding: 7px 13px 7px 9px; }
.ctl-gauge-num { font-size: 21px; font-weight: 700; letter-spacing: -.03em; line-height: 1;
                 color: var(--ctl-ink); font-variant-numeric: tabular-nums; }
.ctl-gauge-meta { font-size: 11px; color: var(--ctl-faint); line-height: 1.35; }

/* Severity rows. Severity is an ORDERED status scale, so it gets one hue
   stepped light-to-dark, not four separate warm hues — red against orange
   against amber is indistinguishable to a colour-blind reader, and every row
   carries its name in text regardless. */
.ctl-sev-dot { width: 9px; height: 9px; border-radius: 2px; flex: none; display: block; }
.ctl-sev-critical { background: #7f1d1d; }
.ctl-sev-high     { background: #b91c1c; }
.ctl-sev-medium   { background: #ef4444; }
.ctl-sev-low      { background: #f87171; }
.ctl-sev-info     { background: var(--ctl-faint); }

/* A part-to-whole strip. 2px surface gaps between fills, per the mark spec. */
.ctl-stack { display: flex; gap: 2px; height: 10px; }
.ctl-stack > span { display: block; border-radius: 2px; }
.ctl-stack > span:first-child { border-radius: 5px 2px 2px 5px; }
.ctl-stack > span:last-child  { border-radius: 2px 5px 5px 2px; }

/* A denser table, for a wide grid of small values — the platform console's
   network list, where eight columns of counts otherwise spend 320px on cell
   padding alone and force a horizontal scrollbar on a laptop. */
/* Reserve room for a two-word network name only where there is room to
   reserve; below the fit threshold the cell shrinks and the name wraps. */
@media (min-width: 1401px) { .ctl-name-cell { min-width: 176px; } }

.ctl-table-compact th,
.ctl-table-compact td { padding-left: 12px; padding-right: 12px; }
.ctl-table-compact td { font-size: 13px; }
/* On a dense table the HEADERS are what set the minimum width — the values are
   two or three digits, while "MEMBERS" in wide uppercase tracking needs 80px.
   Tightening the header alone buys back ~40px across six columns. */
.ctl-table-compact thead th { font-size: 10px; letter-spacing: .05em; }

/* A long hostname is the table's width floor — it cannot shrink and no amount
   of trimming elsewhere gets past it. Below the width where the table fits, let
   it break instead, so a narrow window wraps one cell rather than scrolling the
   whole table sideways. Two lines of hostname beats a scrollbar. */
/* Between the point where the sidebar still takes its full 296px and the point
   where the shell reflows, the content column is at its tightest — so the shell
   gives back some of its own padding there rather than letting a table scroll. */
@media (max-width: 1200px) {
  .ctl-main { padding-left: 1rem; padding-right: 1rem; }
  .max-w-7xl.px-6 { padding-left: .75rem; padding-right: .75rem; }
}

@media (max-width: 1400px) {
  .ctl-break-anywhere { overflow-wrap: anywhere; word-break: break-word; }
  /* Anything held on one line above the fit threshold has to be allowed to
     wrap below it, or a single nowrap cell re-creates the scrollbar the rest of
     this work removed. */
  .ctl-nowrap-wide { white-space: normal; }
}

/* ── Tool tiles ───────────────────────────────────────────────────────────
   Square cards in a grid. `aspect-ratio: 1` sets the shape, but the tile is
   also given a min-height and allowed to grow past the square — a tile that
   clips its own description to stay geometrically perfect is a worse tile.
   The three rows (mark, text, action) are a grid so the button sits on the
   same baseline across the row no matter how long the copy is. */
.ctl-tile {
  aspect-ratio: 1 / 1;
  min-height: 250px;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 12px;
  padding: 18px;
  background: var(--ctl-surface);
  border: 1px solid var(--ctl-border);
  border-radius: var(--ctl-radius);
  transition: border-color .15s ease;
}
.ctl-tile:hover { border-color: #c9d6ea; }
/* Not built yet: recessive, so the live tools read first. */
.ctl-tile.is-planned { background: var(--ctl-tint); }
.ctl-tile.is-planned .ctl-tile-mark { opacity: .5; }
.ctl-tile.is-planned .ctl-tile-name { color: var(--ctl-muted); }

.ctl-tile-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ctl-tile-mark {
  width: 38px; height: 38px; flex: none;
  border-radius: 10px;
  background: var(--ctl-blue-soft);
  color: var(--ctl-blue);
  display: grid; place-items: center;
  font-size: 13px; font-weight: 600; letter-spacing: .02em;
}

.ctl-tile-body { min-width: 0; overflow: hidden; }
.ctl-tile-name { font-size: 15px; font-weight: 600; letter-spacing: -.01em;
                 color: var(--ctl-ink); }
.ctl-tile-tagline { font-size: 11.5px; margin-top: 2px; color: var(--ctl-faint); }
/* Clamped rather than truncated at a character count: the cut lands on a line
   boundary and adapts to the tile's real width. */
.ctl-tile-desc {
  font-size: 12.5px; line-height: 1.5; margin-top: 8px; color: var(--ctl-body);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6;
  overflow: hidden;
}
.ctl-tile-foot { align-self: end; }

/* A usable tool's whole tile is the link, so the click target is the thing the
   member is looking at rather than a button in the corner of a square. */
a.ctl-tile-link { color: inherit; text-decoration: none; }
a.ctl-tile-link:hover { border-color: var(--ctl-blue); }
a.ctl-tile-link:focus-visible {
  outline: 2px solid var(--ctl-blue);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  /* One per row on a phone, where a square would waste most of the screen. */
  .ctl-tile { aspect-ratio: auto; min-height: 0; }
  .ctl-tile-desc { -webkit-line-clamp: 3; }
}

/* ============================================================================
   Tailwind utility remap
   ----------------------------------------------------------------------------
   ~450 inherited `slate-*` / `blue-*` utilities in the templates. Tailwind's
   slate is close to but not on the TLN palette, so they are remapped here in one
   place rather than edited across 44 files. Loads after the Tailwind CDN and
   matches its specificity, so it wins on order.

   New markup should use the semantic classes above.
   ========================================================================= */
.text-slate-900, .text-slate-800, .text-slate-700 { color: var(--ctl-ink) !important; }
.text-slate-600 { color: var(--ctl-body) !important; }
.text-slate-500 { color: var(--ctl-muted) !important; }
.text-slate-400, .text-slate-300 { color: var(--ctl-faint) !important; }

.bg-slate-50  { background-color: var(--ctl-tint) !important; }
.bg-slate-100 { background-color: var(--ctl-sunk) !important; }
.bg-slate-200 { background-color: #e2e7ef !important; }

.border-slate-100, .border-slate-200 { border-color: var(--ctl-border-soft) !important; }
.border-slate-300, .border-slate-400 { border-color: var(--ctl-border) !important; }

.text-blue-600, .text-blue-700 { color: var(--ctl-blue) !important; }
.bg-blue-500, .bg-blue-600 { background-color: var(--ctl-action) !important; }
.bg-blue-700, .hover\:bg-blue-700:hover { background-color: var(--ctl-action-hover) !important; }
.bg-blue-50, .bg-blue-100 { background-color: var(--ctl-info-bg) !important; }
.border-blue-200, .border-blue-400 { border-color: #bcd3f7 !important; }
.bg-violet-600, .bg-violet-500 { background-color: var(--ctl-action) !important; }
.text-violet-600 { color: var(--ctl-blue) !important; }
.border-violet-400 { border-color: var(--ctl-blue) !important; }
.bg-violet-50 { background-color: var(--ctl-blue-soft) !important; }
.text-indigo-300, .text-indigo-400 { color: var(--ctl-blue) !important; }
.border-indigo-500 { border-color: var(--ctl-blue) !important; }
.bg-indigo-500 { background-color: var(--ctl-action) !important; }

/* ============================================================================
   Auth pages — auth/_layout.html, driven by static/js/auth-fx.js
   ----------------------------------------------------------------------------
   Split screen: a navy brand panel with a live constellation in the logo's
   colours, and the form on the light ground. Cursor effects — the spotlight
   on the panel and the glow on the card's edge — read the pointer position
   from custom properties, and are off on touch screens and under reduced
   motion (auth-fx.js simply does not start them). Without the script this is
   a still, complete page. A trailing cursor ring was tried and removed at the
   owner's request: the effects follow the pointer, they do not replace it.
   ========================================================================= */
.ctl-auth { background: var(--ctl-ground); }
.ctl-auth-shell { display: flex; min-height: 100vh; }

/* ── The brand panel ───────────────────────────────────────────────────── */
.ctl-auth-hero {
  position: relative;
  flex: 0 0 46%;
  max-width: 680px;
  overflow: hidden;
  color: #fff;
  background:
    radial-gradient(60rem 40rem at 110% 110%, rgba(23,105,224,0.55), transparent 60%),
    radial-gradient(40rem 30rem at -10% -10%, rgba(34,211,238,0.14), transparent 60%),
    #0b1f3a;
  --mx: 50%; --my: 40%;
}
.ctl-auth-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* The spotlight that follows the cursor across the panel. */
.ctl-auth-spot {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(22rem 22rem at var(--mx) var(--my),
              rgba(61,139,255,0.22), transparent 70%);
  transition: opacity 400ms ease;
}
.ctl-auth-hero-inner {
  position: relative; z-index: 1;
  height: 100%;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 44px 56px 36px;
}
.ctl-auth-pitch { position: relative; max-width: 30rem; }
/* A soft navy backing so constellation dots drifting under the copy never
   cut through a letter. Blurred, so it reads as depth rather than a box. */
.ctl-auth-pitch::before {
  content: ""; position: absolute; inset: -40px -60px -40px -70px; z-index: -1;
  background: radial-gradient(closest-side, rgba(11,31,58,0.85), rgba(11,31,58,0) 100%);
  pointer-events: none;
}
.ctl-auth-kicker {
  font-size: 12px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: #7fb3ff;
  animation: ctl-rise-in 600ms 100ms cubic-bezier(.2,.7,.2,1) backwards;
}
.ctl-auth-headline {
  margin-top: 14px;
  font-size: clamp(30px, 3.1vw, 44px); line-height: 1.1; font-weight: 700;
  letter-spacing: -0.03em;
  animation: ctl-rise-in 700ms 180ms cubic-bezier(.2,.7,.2,1) backwards;
}
.ctl-auth-headline span {
  background: linear-gradient(90deg, #3d8bff, #22d3ee 55%, #f5b942);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ctl-auth-points { margin-top: 32px; display: grid; gap: 14px; }
.ctl-auth-points li {
  display: flex; align-items: center; gap: 14px;
  font-size: 15px; color: rgba(255,255,255,0.82);
  animation: ctl-rise-in 600ms cubic-bezier(.2,.7,.2,1) backwards;
  animation-delay: calc(300ms + var(--i) * 90ms);
}
.ctl-auth-point-icon {
  width: 38px; height: 38px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 11px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.12);
  color: #7fb3ff;
  backdrop-filter: blur(4px);
}
.ctl-auth-legal { font-size: 12px; color: rgba(255,255,255,0.45); }

/* ── The form column ───────────────────────────────────────────────────── */
.ctl-auth-main {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  padding: 40px 24px;
}
.ctl-auth-column { width: 100%; max-width: 440px; }
.ctl-auth-column.ctl-auth-column-wide { max-width: 560px; }
.ctl-auth-mobile-logo { display: none; justify-content: center; margin-bottom: 28px; }
.ctl-auth-legal-mobile { display: none; text-align: center; font-size: 12px; color: var(--ctl-faint); margin-top: 20px; }

.ctl-auth-card {
  position: relative;
  background: var(--ctl-surface);
  border: 1px solid var(--ctl-border);
  border-radius: 18px;
  padding: 36px 34px 32px;
  box-shadow: 0 1px 2px rgba(11,31,58,.04), 0 24px 48px -24px rgba(11,31,58,.18);
  animation: ctl-rise-in 520ms cubic-bezier(.2,.7,.2,1) backwards;
  --gx: 50%; --gy: 0%; --glow: 0;
}
/* The edge glow: a gradient border masked to the 1px ring, centred on the
   cursor. --glow fades it in only while the pointer is near the card. */
.ctl-auth-card::before {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; padding: 1px;
  background: radial-gradient(18rem 18rem at var(--gx) var(--gy),
              rgba(23,105,224,0.9), rgba(34,211,238,0.5) 35%, transparent 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: var(--glow); transition: opacity 300ms ease;
  pointer-events: none;
}
.ctl-auth-card .ctl-input { padding-top: .75rem; padding-bottom: .75rem; }

.ctl-auth-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 26px 0 18px;
  font-size: 12px; color: var(--ctl-faint);
}
.ctl-auth-divider::before, .ctl-auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--ctl-divider);
}
.ctl-auth-back { font-size: 14px; color: var(--ctl-blue); }
.ctl-auth-back:hover { text-decoration: underline; }

.ctl-auth-alert {
  margin-bottom: 18px; padding: 12px 14px; border-radius: 12px;
  font-size: 14px; line-height: 1.5; border: 1px solid transparent;
  animation: ctl-rise-in 300ms ease backwards;
}
.ctl-auth-alert-bad  { background: var(--ctl-bad-bg);  color: var(--ctl-bad);  border-color: #f7d3cf; }
.ctl-auth-alert-good { background: var(--ctl-good-bg); color: var(--ctl-good); border-color: #c8ecd6; }
.ctl-auth-alert-warn { background: var(--ctl-warn-bg); color: var(--ctl-warn); border-color: #f1dfbd; }
.ctl-auth-alert-info { background: var(--ctl-info-bg); color: var(--ctl-body); border-color: #d6e4fb; }

/* Show / hide password — the button auth-fx.js adds inside the field. */
.ctl-pw-wrap { position: relative; }
.ctl-pw-wrap .ctl-input { padding-right: 2.75rem; }
.ctl-pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 8px; color: var(--ctl-faint);
  transition: color 140ms ease, background 140ms ease;
}
.ctl-pw-toggle:hover { color: var(--ctl-ink); background: var(--ctl-sunk); }
.ctl-pw-toggle:focus-visible { outline: 2px solid var(--ctl-blue); outline-offset: 1px; }

/* Submit in flight: the label gives way to a spinner. */
.ctl-btn.is-busy { position: relative; color: transparent !important; pointer-events: none; }
.ctl-btn.is-busy::after {
  content: ""; position: absolute; width: 18px; height: 18px; border-radius: 999px;
  border: 2px solid rgba(255,255,255,0.45); border-top-color: #fff;
  animation: ctl-spin 700ms linear infinite;
}
.ctl-btn-ghost.is-busy::after { border-color: var(--ctl-border); border-top-color: var(--ctl-blue); }
@keyframes ctl-spin { to { transform: rotate(360deg); } }

@media (max-width: 1023px) {
  .ctl-auth-hero { display: none; }
  .ctl-auth-mobile-logo, .ctl-auth-legal-mobile { display: flex; }
  .ctl-auth-legal-mobile { display: block; }
  .ctl-auth-main { align-items: flex-start; padding-top: 48px; }
}
@media (max-width: 480px) {
  .ctl-auth-card { padding: 28px 22px 24px; border-radius: 16px; }
  .ctl-auth-mobile-logo .tln-mark { height: 36px; }
  .ctl-auth-mobile-logo .tln-logo-name { font-size: 14px; }
}
