/* Subnet & VLAN Plan — a sheet you read at 2am.
 *
 * The site preset is `terminal`, and this leans into it rather than fighting
 * it: every address, prefix and count is monospaced and tabular, because the
 * whole job is comparing numbers that differ in one octet. A proportional
 * font here is the difference between spotting an overlap and not.
 *
 * Three states carry colour and nothing else does:
 *
 *   --product-signal  a figure that checks out. Used sparingly — mostly on
 *                     the "nothing outstanding" verdict, because a page where
 *                     everything is green teaches nothing.
 *   --product-alarm   something that will break. An overlap, a DHCP pool
 *                     outside its subnet, a VLAN outgrown. These are not
 *                     warnings; they are the 2am call.
 *   --product-warn    something that might. A gateway inside the pool, a
 *                     static address in the DHCP range. Real, but survivable,
 *                     and mixing the two would flatten the distinction the
 *                     reader most needs.
 *
 * The intent matrix is the one piece of deliberate visual density: it is read
 * as a grid, clicked through quickly, and its whole value is that a hole in
 * the segmentation is visible from across the room.
 */

.product[data-product="subnet-planner"] {
  --product-ink: #0c1116;
  --product-paper: #eef2f5;
  --product-signal: #45896f;
  --product-alarm: #a8452f;
  --product-warn: #96712c;
  --product-quiet: #6f7a83;
  --sp-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ── Rows ──────────────────────────────────────────────────────────── */

.sp-rows {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .45rem;
}

.sp-row {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  padding: .75rem .9rem;
  border: 1px solid var(--border);
  border-left: .25rem solid var(--border);
  border-radius: .35rem;
  background: var(--surface);
}

.sp-row > div:first-child { min-width: 0; }
.sp-row .field-help { margin: .25rem 0 0; }
.sp-row .tool-actions { margin: 0; flex: 0 0 auto; }

.sp-row--active { border-left-color: var(--product-signal); }

/* A VLAN or a reservation with something wrong. The left rule is the fastest
   thing to scan down a list of twelve, which is what somebody does first. */
.sp-row--bad {
  border-left-color: var(--product-alarm);
  background: color-mix(in srgb, var(--surface) 90%, var(--product-alarm));
}
.sp-row--warn { border-left-color: var(--product-warn); }
.sp-row--note { border-left-color: var(--product-quiet); }

.sp-row--editing { display: block; border-left-color: var(--product-signal); }
.sp-editor { width: 100%; }

.sp-row-title {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: baseline;
  margin: 0;
  font-weight: 650;
}

.sp-heading { margin: 1.75rem 0 .3rem; font-size: 1.05rem; }

.sp-provenance {
  padding-left: .6rem;
  border-left: 2px solid var(--border);
  font-style: italic;
}

/* ── Addresses ─────────────────────────────────────────────────────── */

/* Monospaced and tabular everywhere. The job is comparing numbers that differ
   in one octet, and a proportional font is the difference between seeing an
   overlap and not. */
.sp-address,
.sp-badge--cidr,
.sp-vid,
.sp-fact-value,
.sp-table .sp-cell-num {
  font-family: var(--sp-mono);
  font-variant-numeric: tabular-nums;
}

.sp-address { font-weight: 700; }

/* The VLAN ID, which is the thing a switch port is tagged with and therefore
   the thing somebody types into a console. Boxed so it reads as an
   identifier rather than as part of the name. */
.sp-vid {
  padding: .05rem .35rem;
  border: 1px solid var(--border);
  border-radius: .2rem;
  color: var(--muted);
  font-size: .78rem;
  font-weight: 700;
}

/* ── Badges ────────────────────────────────────────────────────────── */

.sp-badge {
  padding: .1rem .45rem;
  border-radius: .22rem;
  background: color-mix(in srgb, var(--muted) 14%, transparent);
  color: var(--muted);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.sp-badge--cidr {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  letter-spacing: 0;
  text-transform: none;
  font-size: .8rem;
}

.sp-badge--active {
  background: color-mix(in srgb, var(--product-signal) 18%, transparent);
  color: color-mix(in srgb, var(--product-signal) 92%, var(--text));
}

.sp-badge--bad {
  background: color-mix(in srgb, var(--product-alarm) 18%, transparent);
  color: color-mix(in srgb, var(--product-alarm) 92%, var(--text));
}

.sp-badge--warn {
  background: color-mix(in srgb, var(--product-warn) 20%, transparent);
  color: color-mix(in srgb, var(--product-warn) 92%, var(--text));
}

/* ── Facts on a VLAN ───────────────────────────────────────────────── */

.sp-facts {
  margin: .4rem 0 .15rem;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .2rem 1.3rem;
}

.sp-facts li { display: flex; flex-direction: column; gap: .02rem; }

.sp-fact-label {
  color: var(--muted);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}

.sp-fact-value { font-size: .92rem; font-weight: 600; }

/* ── Problems ──────────────────────────────────────────────────────── */

.sp-problems {
  margin: .45rem 0 .1rem;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .18rem;
}

.sp-problem {
  padding: .2rem .5rem .2rem .55rem;
  border-left: .18rem solid var(--border);
  border-radius: .18rem;
  font-size: .88rem;
  line-height: 1.45;
}

/* Will break. Not a warning — the 2am call. */
.sp-problem--bad {
  border-left-color: var(--product-alarm);
  background: color-mix(in srgb, var(--surface) 86%, var(--product-alarm));
  font-weight: 600;
}

/* Might break. Real but survivable, and flattening this into the same colour
   as an overlap would cost the reader the distinction they most need. */
.sp-problem--warn {
  border-left-color: var(--product-warn);
  background: color-mix(in srgb, var(--surface) 90%, var(--product-warn));
}

.sp-problem--note { border-left-color: var(--product-quiet); color: var(--muted); }

.sp-verdict { font-weight: 600; }
.sp-verdict--bad { color: color-mix(in srgb, var(--product-alarm) 92%, var(--text)); }
.sp-verdict--warn { color: color-mix(in srgb, var(--product-warn) 92%, var(--text)); }
.sp-verdict--clean { color: color-mix(in srgb, var(--product-signal) 92%, var(--text)); }

.sp-preview {
  margin-top: .9rem;
  padding: .6rem .8rem;
  border-left: .2rem solid var(--product-signal);
  border-radius: .22rem;
  background: color-mix(in srgb, var(--surface) 86%, var(--product-signal));
  font-family: var(--sp-mono);
  font-size: .84rem;
  line-height: 1.55;
}
.sp-preview--warn {
  border-left-color: var(--product-alarm);
  background: color-mix(in srgb, var(--surface) 86%, var(--product-alarm));
}

/* ── The intent matrix ─────────────────────────────────────────────── */

/* Deliberately dense. Its whole value is that a hole in the segmentation is
   visible from across the room, and a matrix with comfortable padding is one
   that does not fit on screen. */
.sp-matrix { margin: 1rem 0 .4rem; }

.sp-matrix th[scope="col"],
.sp-matrix th[scope="row"] {
  font-size: .8rem;
  font-weight: 650;
  white-space: nowrap;
}

.sp-matrix .sp-cell { padding: .1rem; text-align: center; }
.sp-matrix .sp-cell--self { color: var(--muted); }

.sp-cell-button {
  width: 100%;
  min-width: 2.2rem;
  min-height: 2.2rem;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: .2rem;
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.sp-cell-button--allow {
  border-color: color-mix(in srgb, var(--product-signal) 60%, var(--border));
  background: color-mix(in srgb, var(--surface) 78%, var(--product-signal));
  color: color-mix(in srgb, var(--product-signal) 95%, var(--text));
}

.sp-cell-button--deny {
  border-color: var(--border);
  background: color-mix(in srgb, var(--surface) 92%, var(--muted));
  color: var(--muted);
}

/* Undecided. Marked, because "we never decided" and "we decided no" are
   different states and only the first one is a surprise at 2am. */
.sp-cell-button--unset {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--product-warn) 55%, var(--border));
  color: color-mix(in srgb, var(--product-warn) 92%, var(--text));
}

.sp-cell-button:focus-visible {
  outline: 3px solid var(--product-signal);
  outline-offset: -3px;
}

.sp-exceptions {
  margin: .6rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .2rem;
}

.sp-exception {
  display: flex;
  gap: .8rem;
  align-items: baseline;
  justify-content: space-between;
  padding: .25rem .5rem;
  border: 1px solid var(--border);
  border-radius: .25rem;
  background: var(--surface);
  font-family: var(--sp-mono);
  font-size: .85rem;
}

/* ── The sheet ─────────────────────────────────────────────────────── */

.sp-table { margin: 1rem 0 0; }
.sp-table .sp-cell-num { white-space: nowrap; }

.sp-takeaway {
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.sp-takeaway h3 { margin: 0 0 .35rem; }

.sp-print-head,
.sp-print-caveat { display: none; }

@media (max-width: 52rem) {
  /* The matrix is the one thing that genuinely cannot become cards — it is a
     grid or it is nothing — so it scrolls sideways inside its own box rather
     than pushing the page. */
  .sp-matrix { display: block; overflow-x: auto; }

  .sp-table,
  .sp-table tbody,
  .sp-table th,
  .sp-table td { display: block; }
  .sp-table thead { display: none; }
  .sp-table tbody tr {
    margin-bottom: .5rem;
    padding: .6rem .75rem;
    border: 1px solid var(--border);
    border-radius: .35rem;
  }
  .sp-table tbody th[scope="row"] { margin-bottom: .3rem; font-size: 1rem; }
  .sp-table tbody td {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .08rem 0;
  }
  .sp-table tbody td::before {
    content: attr(data-label);
    color: var(--muted);
    font-family: inherit;
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
  }
}

@media (max-width: 44rem) {
  .sp-row { flex-direction: column; }
  .sp-row .tool-actions { align-self: flex-end; }
}

@media print {
  /* The whole reason this product has a print artifact. When the network is
     down this page is unreachable, so the sheet has to be on paper — and it
     has to fit on as few sheets as possible, because somebody is holding it
     in one hand. */
  @page { size: portrait; margin: 12mm; }

  .sp-print-head { display: block; }
  .sp-print-head h2 { margin: 0 0 .2rem; font-size: 14pt; }
  .sp-print-head p { margin: 0 0 .7rem; font-size: 8.5pt; color: #444; }

  .sp-print-caveat {
    display: block;
    margin-top: .7rem;
    padding-top: .4rem;
    border-top: .5pt solid #999;
    font-size: 8pt;
    color: #333;
  }

  .sp-table { width: 100%; font-size: 9.5pt; }
  .sp-table caption {
    text-align: left;
    font-weight: 700;
    padding-bottom: 1mm;
  }
  .sp-table tr { break-inside: avoid; }
  .sp-table th, .sp-table td { padding: .6mm 2mm .6mm 0; }

  .sp-takeaway, .tool-inputs, .pane-form, .tool-actions,
  .sp-problems, .sp-matrix { display: none; }
}
