/* Kanata product site.
   One stylesheet, no external requests.

   Light, quiet and mostly white. The palette is the console's own light theme,
   value for value, from internal/web/assets/styles.css — including the accent,
   which really is that purple. A site painted in colours the product does not
   use makes the live demo on it look like a mock-up even when it is the real
   component. */

:root {
  --bg:            #f4f5f7;
  --bg-raised:     #ffffff;
  --bg-sunken:     #eceef2;
  --bg-hover:      #f0f2f6;
  --border:        #e4e7ec;
  --border-strong: #c6ccd8;

  --text:      #16181d;
  --text-dim:  #5b6472;
  --text-mute: #8b93a1;

  --accent:      #4f46e5;
  --accent-2:    #7c6cf5;
  --accent-soft: #eef0fe;

  --ink:       #111114;   /* the black used on buttons and headings */
  --ink-hover: #26262c;

  --ok:     #12805c;
  --warn:   #a35a06;
  --danger: #c62f3d;
  --info:   #1667a8;

  --shadow-xs: 0 1px 2px rgb(20 22 28 / .04);
  --shadow-sm: 0 2px 8px rgb(20 22 28 / .05), 0 1px 2px rgb(20 22 28 / .04);
  --shadow-md: 0 10px 30px rgb(20 22 28 / .07), 0 2px 6px rgb(20 22 28 / .04);
  --shadow-lg: 0 26px 70px rgb(20 22 28 / .10), 0 4px 12px rgb(20 22 28 / .05);

  --radius:    16px;
  --radius-sm: 10px;
  --radius-lg: 26px;

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --page: 1180px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 92px; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.wrap { width: 100%; max-width: var(--page); margin: 0 auto; padding: 0 24px; position: relative; }

a { color: inherit; }

h1, h2, h3, h4 { margin: 0; font-weight: 620; line-height: 1.08; letter-spacing: -0.035em; }
h1 { font-size: clamp(2.7rem, 6.4vw, 4.4rem); letter-spacing: -0.05em; }
h2 { font-size: clamp(2rem, 4.4vw, 3.15rem); letter-spacing: -0.045em; }
h3 { font-size: 1.14rem; letter-spacing: -0.02em; }
p  { margin: 0; }

.lede  { font-size: clamp(1rem, 1.6vw, 1.13rem); color: var(--text-dim); line-height: 1.6; }
.muted { color: var(--text-mute); }
.small { font-size: .875rem; }
.mono  { font-family: var(--mono); }

/* ---------------------------------------------------------------- header -- */

header.top {
  position: sticky; top: 0; z-index: 50;
  background: rgba(244, 245, 247, .78);
  backdrop-filter: saturate(180%) blur(14px);
}
.top-in { display: flex; align-items: center; gap: 26px; height: 76px; }
.brand {
  display: flex; align-items: center; gap: 10px; text-decoration: none;
  font-weight: 600; letter-spacing: -0.03em; font-size: 1.08rem;
}
.brand svg { display: block; border-radius: 7px; }
.top nav { display: flex; gap: 4px; margin-left: auto; }
.top nav a {
  color: var(--text-dim); text-decoration: none; font-size: .9rem;
  padding: 7px 12px; border-radius: 999px; transition: background .16s, color .16s;
}
.top nav a:hover { color: var(--text); background: rgba(255,255,255,.8); }
.top .cta { margin-left: 10px; }

@media (max-width: 900px) {
  .top nav { display: none; }
  /* The nav was what pushed the action to the right; without it the button
     ends up sitting against the logo. */
  .top .cta { margin-left: auto; }
}

/* --------------------------------------------------------------- buttons --
   Pill shaped, and the important one is black rather than coloured. The accent
   is left to do one job on this page — marking what matters inside the product
   screens — and a purple call to action would compete with it. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border: 1px solid var(--border); background: var(--bg-raised); color: var(--text);
  padding: 13px 24px; border-radius: 999px; font: inherit; font-size: .95rem;
  font-weight: 500; cursor: pointer; text-decoration: none; white-space: nowrap;
  box-shadow: var(--shadow-xs);
  transition: background .18s, border-color .18s, transform .18s, box-shadow .18s, color .18s;
}
.btn:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn .dot {
  width: 21px; height: 21px; border-radius: 50%; background: var(--ink); color: #fff;
  display: grid; place-items: center; font-size: .68rem; flex: none;
  transition: transform .22s cubic-bezier(.22,.61,.36,1);
}
.btn:hover .dot { transform: translateX(3px); }

.btn.primary { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn.primary:hover { background: var(--ink-hover); border-color: var(--ink-hover); }
.btn.primary .dot { background: #fff; color: var(--ink); }
.btn.sm { padding: 9px 18px; font-size: .875rem; }
.btn.wide { width: 100%; }

/* ------------------------------------------------------------------ hero -- */

.hero { padding: 72px 0 56px; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--bg-raised); border: 1px solid var(--border);
  padding: 7px 15px 7px 11px; border-radius: 999px; font-size: .8rem; color: var(--text-dim);
  box-shadow: var(--shadow-xs);
}
.eyebrow b { color: var(--text); font-weight: 560; }
.hero .dot-live { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex: none; }
.hero h1 { margin: 26px 0 0; max-width: 16ch; }
.hero h1 .grad { color: var(--text-mute); }
.hero .lede { margin-top: 24px; max-width: 56ch; }
.hero .actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
.hero .assurance {
  display: flex; flex-wrap: wrap; gap: 10px 28px; margin-top: 44px;
  padding-top: 26px; border-top: 1px solid var(--border);
  color: var(--text-mute); font-size: .85rem;
}
.hero .assurance span { display: inline-flex; align-items: center; gap: 8px; }
.hero .assurance i { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); flex: none; }

/* --------------------------------------------------------------- section -- */

.section { padding: 90px 0; }

/* Centred, numbered, with a lot of air above the heading. The number is not
   decoration: it tells a visitor how far through the argument they are. */
.section-head { max-width: 62ch; margin: 0 auto 40px; text-align: center; }
.section-head .kicker {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 14px; margin-bottom: 22px;
  font-size: .7rem; text-transform: uppercase; letter-spacing: .14em;
  font-weight: 620; color: var(--text-dim);
}
.section-head .kicker .n { color: var(--text-mute); font-variant-numeric: tabular-nums; }
.section-head .kicker i { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
.section-head p { margin: 18px auto 0; }

.panel { background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.panel-body { padding: 20px; }

/* ---------------------------------------------------------------- chips --- */

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--border); background: var(--bg-raised); color: var(--text-dim);
  border-radius: 999px; padding: 5px 12px; font-size: .8rem; cursor: pointer;
  font-family: inherit; transition: background .15s, color .15s, border-color .15s;
}
.chip:hover { border-color: var(--border-strong); color: var(--text); }
/* Pressed reads as selected, not as a button. Filled black was too loud for a
   row where five chips out of five are normally on — the toolbar became a bar
   of black before a visitor had looked at anything. */
.chip[aria-pressed="true"] {
  background: var(--accent-soft); border-color: rgba(79,70,229,.26); color: var(--accent); font-weight: 540;
}
.chip .swatch { width: 8px; height: 8px; border-radius: 2px; }

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  border-radius: 999px; padding: 3px 10px; font-size: .74rem; font-weight: 560;
  background: var(--bg-sunken); color: var(--text-dim); border: 1px solid transparent;
}
.pill.ok     { color: #0d6b4d; background: #e3f5ee; }
.pill.warn   { color: #8a4d05; background: #fbf0dd; }
.pill.danger { color: #a92433; background: #fce9eb; }
.pill.info   { color: #12558c; background: #e6f0f9; }

/* ======================================================= the console frame ==
   The demo sections are framed the way the console itself is framed: the same
   navigation rail, the same items, the same icons. Without it each mock is a
   floating card that could belong to anything; with it a visitor is looking at
   the application, which is the thing being sold. */

.app {
  position: relative;
  display: grid; grid-template-columns: 212px 1fr;
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow-lg);
}
.app-side { background: #fbfbfc; border-right: 1px solid var(--border); padding: 18px 12px; }
.app-brand { display: flex; align-items: center; gap: 9px; padding: 2px 8px 20px; font-weight: 600; font-size: .95rem; letter-spacing: -0.02em; }
.app-brand svg { border-radius: 6px; }
.app-nav { display: grid; gap: 2px; }
.app-nav .item {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 11px; border-radius: 9px;
  color: var(--text-dim); font-size: .875rem; cursor: default;
}
.app-nav .item svg { flex: none; opacity: .6; }
.app-nav .item .badge {
  margin-left: auto; font-size: .7rem; font-variant-numeric: tabular-nums;
  background: var(--bg-sunken); color: var(--text-mute); border-radius: 999px; padding: 1px 8px;
}
.app-nav .item.on { background: var(--accent-soft); color: var(--accent); font-weight: 540; }
.app-nav .item.on svg { opacity: 1; }
.app-nav .group {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .13em;
  color: var(--text-mute); font-weight: 640; padding: 18px 11px 6px;
}
.app-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 16px 20px; border-bottom: 1px solid var(--border);
}
.app-head .h { font-weight: 600; font-size: 1.02rem; letter-spacing: -0.02em; margin-right: auto; }
.app-head .who { display: flex; align-items: center; gap: 8px; font-size: .8rem; color: var(--text-mute); }
.app-head .avatar {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-size: .68rem; font-weight: 700;
}
.app-main { min-width: 0; }
.app-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 20px; border-bottom: 1px solid var(--border); background: #fbfbfc;
}
.app-toolbar .lbl { font-size: .74rem; text-transform: uppercase; letter-spacing: .1em; color: var(--text-mute); font-weight: 620; }

@media (max-width: 940px) { .app { grid-template-columns: 1fr; } .app-side { display: none; } }

/* -------------------------------------------------------------- topology --
   Class for class, this is the console's own topology screen: a scope bar over
   the map, the panels floating at the top left, the tools at the top right and
   the selected-server drawer on the right. Reproducing the layout rather than
   inventing a tidier one is the point — a visitor should recognise this screen
   when they open the product. */

.scope-bar {
  display: flex; flex-wrap: wrap; gap: 9px; align-items: center;
  padding: 14px 20px; border-bottom: 1px solid var(--border); background: #fbfbfc;
}
.scope-bar .search {
  flex: 1 1 280px; min-width: 200px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-raised); padding: 9px 13px; font: inherit; font-size: .875rem;
  color: var(--text);
}
.scope-bar .search::placeholder { color: var(--text-mute); }
.scope-bar select {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-raised); padding: 9px 12px; font: inherit; font-size: .875rem;
  color: var(--text); cursor: pointer;
}
.scope-chips { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
.scope-chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--accent-soft); border: 1px solid rgba(79,70,229,.2);
  border-radius: 999px; padding: 3px 10px; font-size: .78rem; color: var(--accent);
}
.scope-chip .dot { width: 7px; height: 7px; border-radius: 50%; }
.scope-chip .x { color: var(--accent); opacity: .6; }

.graph-shell { position: relative; height: 520px; background: var(--bg-raised); overflow: hidden; }
.graph-shell canvas { display: block; width: 100%; height: 100%; cursor: grab; }

.graph-overlay {
  position: absolute; top: 14px; left: 14px; z-index: 8;
  display: flex; flex-direction: column; gap: 10px;
  max-width: 272px; max-height: calc(100% - 64px); overflow-y: auto;
}
/* Opaque, like the console's own: a translucent panel over a canvas that
   repaints every frame has to be recomposited every frame, and it shimmers. */
.graph-panel {
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 12px 14px;
  box-shadow: var(--shadow-sm); font-size: 12.5px; line-height: 1.5;
}
.graph-panel h4 {
  font-size: 11px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-mute); margin: 0 0 8px; font-weight: 640;
}
.legend-row { display: flex; align-items: center; gap: 9px; margin-bottom: 6px; cursor: pointer; }
.legend-row:last-child { margin-bottom: 0; }
.legend-row input { width: auto; margin: 0; accent-color: var(--accent); cursor: pointer; }
.legend-line { width: 20px; height: 0; border-top-width: 2.5px; border-top-style: solid; flex: none; }
.legend-row .zdot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* A verdict label is the whole explanation of what a colour means, so it wraps
   rather than being cut off — "Blocked upstream (perime…" tells nobody
   anything. Zone names are the operator's own and can be long without being
   informative, so those alone are clipped. */
.legend-row .grow { flex: 1; min-width: 0; }
.legend-row .grow.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.legend-row .n { color: var(--text-mute); }
.graph-panel .sep { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }

.graph-detail {
  position: absolute; top: 58px; right: 14px; width: 288px; z-index: 9;
  max-height: calc(100% - 76px); overflow-y: auto;
}
.graph-detail .head { display: flex; align-items: center; gap: 8px; }
.graph-detail .head h4 { flex: 1; margin: 0; }
.graph-detail .x {
  border: 0; background: transparent; color: var(--text-mute); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 4px; border-radius: 6px;
}
.graph-detail .x:hover { background: var(--bg-hover); color: var(--text); }
.graph-detail .name { font-weight: 620; margin-top: 6px; }
.graph-detail .ip { font-family: var(--mono); font-size: 11.5px; color: var(--text-mute); }
.graph-detail .pills { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
.graph-detail .big { font-size: 2.1rem; font-weight: 640; letter-spacing: -0.04em; margin-top: 6px; }
.graph-detail .bar { height: 5px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; flex: 1; }
.graph-detail .bar i { display: block; height: 100%; background: var(--accent); }
.graph-detail .way { display: flex; align-items: center; gap: 9px; margin-top: 7px; font-size: 11.5px; }
.port-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.port-chips .pill { font-size: 11px; padding: 1px 7px; font-family: var(--mono); }

.graph-tools { position: absolute; top: 14px; right: 14px; display: flex; gap: 7px; z-index: 10; }
.graph-tools .btn { padding: 7px 14px; font-size: .82rem; box-shadow: var(--shadow-sm); }

.graph-hint {
  position: absolute; bottom: 14px; left: 14px; font-size: 11.5px; color: var(--text-mute);
  background: var(--bg-raised); padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--border); z-index: 7;
}

/* ------------------------------------------------------------- dashboard -- */

.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.tile { background: #fbfbfc; border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; }
.tile .k { font-size: .72rem; color: var(--text-mute); text-transform: uppercase; letter-spacing: .11em; font-weight: 640; }
.tile .v { font-size: 2.2rem; font-weight: 620; letter-spacing: -0.045em; margin-top: 8px; font-variant-numeric: tabular-nums; }
.tile .s { font-size: .8rem; color: var(--text-dim); margin-top: 2px; }
.tile.good .v { color: var(--ok); }
.tile.warn .v { color: var(--warn); }
.tile.bad  .v { color: var(--danger); }

.bars { display: flex; align-items: flex-end; gap: 5px; height: 84px; margin-top: 16px; }
.bars i {
  flex: 1; border-radius: 4px 4px 0 0; display: block;
  background: linear-gradient(180deg, var(--accent), var(--accent-2));
  opacity: .85; transition: height .5s cubic-bezier(.22,.61,.36,1);
}

table.data { width: 100%; border-collapse: collapse; font-size: .87rem; }
table.data th {
  text-align: left; font-size: .68rem; text-transform: uppercase; letter-spacing: .11em;
  color: var(--text-mute); font-weight: 640; padding: 0 10px 10px; border-bottom: 1px solid var(--border);
}
table.data td { padding: 11px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data td.num { text-align: right; font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; }

@media (max-width: 820px) { .tiles { grid-template-columns: repeat(2, 1fr); } }

/* ----------------------------------------------------------- server pick -- */

.split { display: grid; grid-template-columns: 262px 1fr; }
.picker { border-right: 1px solid var(--border); padding: 12px; max-height: 560px; overflow-y: auto; background: #fbfbfc; }
.picker button {
  display: block; width: 100%; text-align: left; background: transparent; border: 0;
  color: var(--text-dim); font: inherit; font-size: .88rem; padding: 9px 12px;
  border-radius: 10px; cursor: pointer; transition: background .15s, color .15s;
}
.picker button:hover { background: var(--bg-hover); color: var(--text); }
.picker button[aria-current="true"] { background: var(--accent-soft); color: var(--accent); font-weight: 540; }
.picker .ip { display: block; font-family: var(--mono); font-size: .73rem; color: var(--text-mute); }
@media (max-width: 820px) { .split { grid-template-columns: 1fr; } .picker { border-right: 0; border-bottom: 1px solid var(--border); max-height: 190px; } }

.detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-bottom: 22px; }
.srv-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
@media (max-width: 820px) { .srv-cols { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- policy -- */

.rule { display: flex; align-items: center; gap: 14px; padding: 14px 20px; border-bottom: 1px solid var(--border); }
.rule:last-of-type { border-bottom: 0; }
.rule .grip { color: var(--border-strong); cursor: grab; flex: none; }
.rule .nm { flex: 1; min-width: 0; }
.rule .nm b { font-weight: 560; }
.rule .nm div { font-size: .79rem; color: var(--text-mute); font-family: var(--mono); }
.rule.off { opacity: .4; }
.folder {
  padding: 11px 20px; font-size: .68rem; text-transform: uppercase; letter-spacing: .13em;
  color: var(--text-mute); font-weight: 640; background: #fbfbfc; border-bottom: 1px solid var(--border);
}

.switch { position: relative; width: 38px; height: 22px; flex: none; border: 0; padding: 0; border-radius: 999px; background: #d8dbe2; cursor: pointer; transition: background .18s; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-xs); transition: transform .18s; }
.switch[aria-pressed="true"] { background: var(--accent); }
.switch[aria-pressed="true"]::after { transform: translateX(16px); }

.deploy-note {
  display: flex; align-items: flex-start; gap: 11px; padding: 14px 16px;
  border-radius: var(--radius-sm); background: var(--accent-soft); font-size: .88rem; color: var(--text-dim);
}
.deploy-note b { color: var(--text); }

/* ------------------------------------------------------- numbered feature --
   The four-up row from a print contents page: a rule down the left, an index
   above the title, and enough space that nothing needs a box drawn round it. */

.numbered { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; }
.numbered .n-item { padding: 26px 26px 8px; border-left: 1px solid var(--border); }
.numbered .n-item:first-child { padding-left: 0; border-left: 0; }
.numbered .idx { font-size: .72rem; letter-spacing: .13em; color: var(--text-mute); font-weight: 620; font-variant-numeric: tabular-nums; }
.numbered .n-item h3 { margin: 26px 0 8px; }
.numbered .n-item p { color: var(--text-dim); font-size: .92rem; }
.numbered .mark { color: var(--accent); }
@media (max-width: 940px) { .numbered { grid-template-columns: repeat(2, 1fr); } .numbered .n-item:nth-child(3) { border-left: 0; padding-left: 0; } }
@media (max-width: 620px) { .numbered { grid-template-columns: 1fr; } .numbered .n-item { border-left: 0; padding-left: 0; } }

/* ----------------------------------------------------------------- cards -- */

.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 30px; }
.card h3 { margin-bottom: 12px; }
.card p { color: var(--text-dim); font-size: .93rem; }
.card .ico {
  width: 38px; height: 38px; border-radius: 12px; background: var(--accent-soft);
  display: grid; place-items: center; color: var(--accent); margin-bottom: 18px; font-size: 1.05rem;
}
@media (max-width: 900px) { .cards { grid-template-columns: 1fr; } }

/* =============================================================== pricing ==
   Two plans and one decision: rent it or own it. The feature list is pulled out
   from under the cards and shown once beneath them, because two identical
   columns of ticks invite a comparison that does not exist here. */

.plans { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; align-items: stretch; }

.plan {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column;
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 34px 32px 32px;
  box-shadow: var(--shadow-sm);
  transition: transform .25s cubic-bezier(.22,.61,.36,1), box-shadow .25s;
}
.plan:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* The featured card carries a soft wash across its top third rather than a
   border in a louder colour: the eye lands on it without the page raising its
   voice, and it is the only place the accent appears at full strength. */
.plan.featured::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 62%; z-index: -1;
  background:
    radial-gradient(120% 100% at 12% 0%, #dcd9fd 0%, transparent 62%),
    radial-gradient(110% 100% at 88% 6%, #f3dcf0 0%, transparent 58%),
    linear-gradient(180deg, #eceafe 0%, rgba(255,255,255,0) 100%);
}

.plan .tag {
  position: absolute; top: 26px; right: 26px;
  font-size: .66rem; text-transform: uppercase; letter-spacing: .13em; font-weight: 700;
  color: var(--accent); background: rgba(255,255,255,.82);
  border: 1px solid rgba(79,70,229,.16); border-radius: 999px; padding: 5px 12px;
  backdrop-filter: blur(6px);
}
.plan .name { font-size: .72rem; text-transform: uppercase; letter-spacing: .14em; font-weight: 660; color: var(--text-mute); }
.plan .price {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-top: 18px; font-size: clamp(2.7rem, 5.4vw, 3.6rem);
  font-weight: 640; letter-spacing: -0.055em; line-height: 1;
}
.plan .price .per { font-size: .92rem; font-weight: 500; color: var(--text-mute); letter-spacing: 0; }
.plan .note { color: var(--text-dim); font-size: .94rem; margin-top: 16px; min-height: 76px; }
.plan .terms { margin-top: 20px; display: grid; gap: 12px; }
.plan .terms div { display: flex; align-items: flex-start; gap: 11px; font-size: .9rem; color: var(--text-dim); }
.plan .terms div::before {
  content: "✓"; flex: none; width: 19px; height: 19px; margin-top: 1px;
  border-radius: 50%; background: var(--bg-sunken); color: var(--text);
  display: grid; place-items: center; font-size: .64rem; font-weight: 700;
}
.plan.featured .terms div::before { background: rgba(255,255,255,.75); color: var(--accent); }
.plan .btn { margin-top: 28px; }

.included { margin-top: 20px; padding: 32px; background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.included .hd { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 24px; }
.included .hd b { font-size: 1.06rem; font-weight: 600; letter-spacing: -0.02em; }
.included .hd span { color: var(--text-mute); font-size: .9rem; }
.included .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 14px 30px; }
.included .grid div { display: flex; align-items: center; gap: 11px; font-size: .92rem; color: var(--text-dim); }
.included .grid div::before {
  content: "✓"; flex: none; width: 19px; height: 19px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center; font-size: .64rem; font-weight: 700;
}

.unlimited {
  display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
  text-align: center; margin-bottom: 22px; padding: 16px 24px;
  border: 1px solid var(--border); background: var(--bg-raised);
  border-radius: 999px; font-size: .94rem; color: var(--text-dim); box-shadow: var(--shadow-xs);
}
.unlimited b { color: var(--text); font-weight: 600; }

@media (max-width: 860px) { .plans { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- closing -- */

.final { text-align: center; padding: 110px 0 100px; }
.final h2 { max-width: 18ch; margin: 0 auto; }
.final .lede { margin: 20px auto 0; max-width: 52ch; }
.final .actions { display: flex; gap: 12px; justify-content: center; margin-top: 36px; flex-wrap: wrap; }

footer.foot { border-top: 1px solid var(--border); padding: 32px 0 56px; color: var(--text-mute); font-size: .85rem; }
.foot-in { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.foot-in .sp { margin-left: auto; }

/* ================================================================ motion ==
   Decoration, all of it. Gated on a class the script adds to <html> before it
   starts observing: hiding content in the stylesheet and revealing it from
   JavaScript means a failed script leaves a blank page, and this way the worst
   case is a page that simply does not animate. */

.js-motion .reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity .7s cubic-bezier(.22,.61,.36,1), transform .7s cubic-bezier(.22,.61,.36,1);
  transition-delay: var(--d, 0ms);
}
.js-motion .reveal.in { opacity: 1; transform: none; }

.lift { transition: transform .24s cubic-bezier(.22,.61,.36,1), box-shadow .24s, border-color .24s; }
.lift:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(18,128,92,.30); }
  70%      { box-shadow: 0 0 0 7px rgba(18,128,92,0); }
}
.hero .dot-live { animation: breathe 3s ease-out infinite; }

/* A line of light crossing each console frame once as it arrives, the way a
   screen wakes up. */
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(330%); } }
.app::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 30%;
  background: linear-gradient(90deg, transparent, rgba(79,70,229,.05), transparent);
  pointer-events: none; opacity: 0; z-index: 3;
}
.js-motion .app.reveal.in::after { animation: sweep 1.6s ease-out .2s 1; opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ================================================================= mobile ==
   The four demo sections are the console itself: a map to drag, a rail of
   navigation, tables that assume a desktop's width. Shrinking them down would
   produce something that works badly and sells nothing, so below the width
   where they stop being usable they are replaced by a note saying where to find
   them. Every argument the page makes in words survives on a phone; only the
   demonstrations wait for a real screen. */

.desk-only { display: none; }

@media (max-width: 900px) {
  /* Shown, but as a picture.
   *
   * Hiding the console outright left a paragraph where the product should be.
   * A phone cannot drive it — the map wants dragging, the tables want width —
   * but it can perfectly well look at it, and the thing being sold is worth
   * seeing before anybody decides whether to find a laptop. Kept live rather
   * than swapped for a screenshot: it is the same renderer drawing the same
   * fleet, so the preview cannot drift out of date, and there is no image to
   * ship on a page that promises to load nothing. */
  .app {
    grid-template-columns: 1fr;
    max-height: 330px;
    pointer-events: none;
    box-shadow: var(--shadow-md);
  }
  /* Faded off at the foot, so it reads as a glimpse rather than as a screen
     that has been cut off. */
  .app::before {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 104px;
    background: linear-gradient(180deg, transparent, var(--bg-raised) 82%);
    z-index: 6; pointer-events: none;
  }
  /* Everything that only makes sense to a pointer. */
  .app-side, .app-toolbar, .scope-bar, .graph-overlay, .graph-tools,
  .graph-hint, .graph-detail, .srv-drawer, .app-head .who,
  .app-head .btn, .picker { display: none; }

  /* The dashboard's two columns are written inline on the element, so this has
     to shout to be heard. Left as they are, the chart and the table share 375
     pixels and the preview shows neither. */
  .dash-cols { grid-template-columns: 1fr !important; }
  .graph-shell { height: 270px; }
  .topo-canvas canvas { height: 270px; }
  .srv-stage { min-height: 0; }
  .split { grid-template-columns: 1fr; }

  .desk-only {
    display: flex; align-items: flex-start; gap: 16px;
    background: var(--bg-raised); border: 1px solid var(--border);
    border-radius: var(--radius-lg); padding: 24px 22px;
    color: var(--text-dim); font-size: .93rem; line-height: 1.55;
    box-shadow: var(--shadow-sm);
  }
  .desk-only svg { color: var(--accent); flex: none; margin-top: 2px; }
  .desk-only b { color: var(--text); font-weight: 600; display: block; margin-bottom: 4px; }
}

@media (max-width: 720px) {
  .wrap { padding: 0 20px; }

  .top-in { height: 64px; gap: 14px; }
  .brand { font-size: 1rem; }

  .hero { padding: 44px 0 40px; }
  .hero h1 { max-width: none; margin-top: 20px; }
  .hero .lede { margin-top: 18px; }
  .hero .actions { margin-top: 26px; }
  .hero .actions .btn { flex: 1 1 auto; justify-content: center; }
  .hero .assurance { margin-top: 32px; padding-top: 20px; gap: 10px 0; flex-direction: column; }
  .hero .assurance span { align-items: flex-start; }
  .hero .assurance i { margin-top: 9px; }

  /* A pill is only a pill while its contents fit on one line. Wrapped inside a
     999px radius the text collides with the curve at both ends, so on a narrow
     screen it becomes an ordinary rounded box that happens to be small. */
  .eyebrow { border-radius: var(--radius); align-items: flex-start; padding: 11px 15px; }
  .hero .dot-live { margin-top: 8px; }

  .section { padding: 58px 0; }
  .section-head { margin-bottom: 28px; }
  .section-head .kicker { margin-bottom: 16px; }

  .card { padding: 24px; }
  .plan { padding: 28px 24px 26px; }
  .plan .note { min-height: 0; }
  .included { padding: 24px 22px; }
  .unlimited { border-radius: var(--radius); padding: 14px 18px; }

  .final { padding: 72px 0 64px; }
  .final .actions .btn { flex: 1 1 auto; justify-content: center; }

  .foot-in { flex-direction: column; align-items: flex-start; gap: 8px; }
  .foot-in .sp { margin-left: 0; }
}

/* Touch pointers get no hover state to discover, so the lift only exists where
   there is a cursor to trigger it. */
@media (hover: none) {
  .lift:hover, .plan:hover, .btn:hover { transform: none; box-shadow: var(--shadow-sm); }
}

/* -------------------------------------------------------------- servers ----
   The fleet list as the console draws it: one row per server, the columns an
   operator actually scans — where it is, what it runs, which zone it belongs
   to, whether it is checking in and whether its firewall is being enforced. */

.srv-count { margin-left: auto; color: var(--text-mute); font-size: .82rem; }

.srv-table { font-size: .875rem; }
.srv-table th:first-child, .srv-table td:first-child { padding-left: 20px; }
.srv-table th:last-child,  .srv-table td:last-child  { padding-right: 20px; }
.srv-table input { accent-color: var(--accent); cursor: pointer; }
.srv-table tbody tr { cursor: pointer; transition: background .12s; }
.srv-table tbody tr:hover { background: var(--bg-hover); }
.srv-table tbody tr.on { background: var(--accent-soft); }
.srv-table .chev { color: var(--text-mute); text-align: right; }
/* A pill that wraps stops being a pill. On a narrow preview the operating
   system is the first thing to run out of room, so it is clipped by the table
   rather than growing into a three-line lozenge. */
.srv-table .pill { white-space: nowrap; }
.srv-table .pill.os   { background: #eef1f6; color: var(--text-dim); font-weight: 500; }
.srv-table .pill.zone { background: var(--accent-soft); color: var(--accent); gap: 6px; }
.srv-table .zdot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }

/* Not a pill: a state is a fact about the server, and boxing it gives it the
   same weight as the firewall mode beside it, which is a decision someone made. */
.state { display: inline-flex; align-items: center; gap: 7px; color: var(--text-dim); }
.state i { width: 7px; height: 7px; border-radius: 50%; background: var(--text-mute); flex: none; }
.state.up { color: var(--text); }
.state.up i { background: var(--ok); }

.row-head {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap;
  padding-bottom: 16px; margin-bottom: 18px; border-bottom: 1px solid var(--border);
}
.row-head span { margin-left: auto; }

/* --------------------------------------------------------- try it live ----
   Placed directly under the on-page demo, where a visitor has just finished
   playing with a map full of invented servers and is best disposed to want a
   real one. */

.live-strip {
  display: flex; align-items: center; gap: 26px; flex-wrap: wrap;
  margin-top: 20px; padding: 24px 28px;
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  color: var(--text-dim); font-size: .95rem;
}
.live-strip > div { flex: 1 1 380px; }
.live-strip b { display: block; color: var(--text); font-weight: 600; margin-bottom: 4px; font-size: 1.02rem; letter-spacing: -0.02em; }
.live-strip .btn { flex: none; }
@media (max-width: 720px) { .live-strip { padding: 22px; } .live-strip .btn { width: 100%; } }

/* ------------------------------------------------------- the server drawer --
   Clicking a row in the console opens the server beside the list rather than
   navigating away from it, so the fleet stays on screen while one of its
   members is read. Reproduced here for the same reason it exists there. */

.srv-stage { position: relative; min-height: 420px; }
.tick { display: inline-flex; align-items: center; gap: 7px; font-size: .85rem; color: var(--text-dim); cursor: pointer; }
.tick input { accent-color: var(--accent); cursor: pointer; }

.srv-drawer {
  position: absolute; inset: 0 0 0 auto; width: 430px; z-index: 5;
  background: var(--bg-raised); border-left: 1px solid var(--border);
  box-shadow: -18px 0 44px rgb(20 22 28 / .07);
  display: flex; flex-direction: column;
}
.srv-drawer[hidden] { display: none; }
.srv-drawer .d-head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 20px 22px 16px; border-bottom: 1px solid var(--border);
}
.srv-drawer .d-head h3 { font-size: 1.2rem; margin: 0; }
.srv-drawer .d-head .os { color: var(--text-mute); font-size: .84rem; }
.srv-drawer .d-head .x {
  margin-left: auto; border: 0; background: transparent; color: var(--text-mute);
  font-size: 17px; line-height: 1; cursor: pointer; padding: 3px 6px; border-radius: 7px;
}
.srv-drawer .d-head .x:hover { background: var(--bg-hover); color: var(--text); }
.srv-drawer .d-body { flex: 1; overflow-y: auto; padding: 20px 22px 22px; }
.srv-drawer .d-foot {
  display: flex; gap: 8px; padding: 14px 22px; border-top: 1px solid var(--border);
  background: #fbfbfc;
}
.srv-drawer .d-foot .btn { padding: 9px 16px; font-size: .85rem; }
.srv-drawer .d-foot .danger { margin-left: auto; background: var(--danger); border-color: var(--danger); color: #fff; }

.d-sec { font-size: .68rem; text-transform: uppercase; letter-spacing: .13em; color: var(--text-mute); font-weight: 640; margin: 24px 0 10px; }
.d-sec:first-child { margin-top: 0; }
.glance { display: grid; grid-template-columns: 140px 1fr; gap: 9px 14px; font-size: .875rem; align-items: baseline; }
.glance dt { color: var(--text-mute); }
.glance dd { margin: 0; }
.srv-drawer table.data { font-size: .82rem; }
.srv-drawer table.data th { padding-bottom: 7px; }
.srv-drawer table.data td { padding: 7px 8px; }
.srv-drawer table.data th:first-child, .srv-drawer table.data td:first-child { padding-left: 0; }

.note-ok, .note-warn {
  padding: 12px 14px; border-radius: var(--radius-sm); font-size: .85rem; line-height: 1.5;
}
.note-ok   { background: #e9f6f1; color: #0d6b4d; }
.note-warn { background: #fdf3e3; color: #8a4d05; }
.note-ok b, .note-warn b { font-weight: 620; }

.d-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.d-filters input, .d-filters select {
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-raised);
  padding: 7px 10px; font: inherit; font-size: .82rem; color: var(--text); min-width: 0;
}
.d-filters input { flex: 1 1 130px; }

@media (max-width: 1100px) { .srv-drawer { width: 100%; border-left: 0; } }

/* ------------------------------------------------------- desktop-only note --
   The demo is the console, and the console assumes a desktop. Saying so when
   the link is tapped is kinder than letting somebody arrive at a waiting room
   that turns them away. */

.sheet {
  position: fixed; inset: 0; z-index: 200; display: grid; place-items: center;
  padding: 22px; background: rgb(16 18 24 / .42); backdrop-filter: blur(3px);
}
.sheet[hidden] { display: none; }
.sheet-card {
  background: var(--bg-raised); border-radius: var(--radius-lg); padding: 30px 26px;
  max-width: 400px; width: 100%; text-align: center; box-shadow: var(--shadow-lg);
}
.sheet-card svg { color: var(--accent); margin-bottom: 14px; }
.sheet-card h3 { font-size: 1.24rem; margin-bottom: 10px; }
.sheet-card p { color: var(--text-dim); font-size: .94rem; }
.sheet-card p + p { margin-top: 10px; }
.sheet-card .btn { margin-top: 22px; }
