/* =============================================================
   Bench — Homepage
   Editorial hero · 5-hue aurora · ticker · spectrum · bento
   ============================================================= */

/* ---------- 1. Hero ------------------------------------------ */

/* The hero carries no glow of its own. Light comes from the fixed
   .atmosphere behind the page and from the console's own bloom, so
   there is exactly one lighting model instead of three stacked ones. */

.hero {
  position: relative;
  padding-block: clamp(40px, 6vw, 78px) clamp(48px, 6vw, 80px);
  isolation: isolate;
}

.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.04fr) minmax(0, 0.96fr);
  align-items: center;
  gap: clamp(28px, 4.5vw, 68px);
}

.hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
}

@media (max-width: 940px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 44px;
    text-align: center;
    justify-items: center;
  }
  .hero__copy { align-items: center; }
}

/* Headline */
.hero h1 {
  max-width: 14ch;
  font-size: clamp(2.85rem, 6.6vw, 5.9rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
  margin: 0;
}

/* The italic serif is already the display move — the emphasis word just
   needs the brand hue, flat. A four-colour sweep across one word is
   decoration competing with the type. */
.hero h1 em {
  font-style: italic;
  color: var(--accent);
  padding-right: 0.07em;
}

.hero .lede {
  max-width: 46ch;
  font-size: clamp(1rem, 1.4vw, 1.12rem);
}

.hero__actions {
  display: flex;
  align-items: center;
  gap: 11px;
  flex-wrap: wrap;
  margin-top: 4px;
}

/* Trust facts as a hairline list rather than floating chips */
.hero__facts {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0;
  margin-top: 6px;
  list-style: none;
  padding: 0;
  font-size: 0.79rem;
  color: var(--ink-3);
}

.hero__facts li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding-inline: 14px;
  border-left: 1px solid var(--line);
}

.hero__facts li:first-child { padding-left: 0; border-left: 0; }

.hero__facts svg { width: 13px; height: 13px; color: var(--ok); flex-shrink: 0; }

@media (max-width: 940px) {
  .hero__facts li:first-child { padding-left: 14px; }
}

/* ---------- 2. Hero stage / console -------------------------- */

.hero__stage {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.mockup-wrap {
  position: relative;
  width: 100%;
  perspective: 1500px;
}

/* Layered card peeking behind, for depth */
.mockup-wrap::after {
  content: '';
  position: absolute;
  inset: 22px -14px -16px 34px;
  z-index: -1;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--solid-2);
  box-shadow: var(--card-shadow);
  transform: rotate(2.1deg);
  pointer-events: none;
}

/* Bloom behind the window */
.mockup-wrap::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 6%;
  width: 96%;
  height: 92%;
  transform: translateX(-50%);
  background:
    radial-gradient(60% 50% at 30% 30%, color-mix(in srgb, var(--n-security) 30%, transparent), transparent 70%),
    radial-gradient(60% 50% at 74% 66%, color-mix(in srgb, var(--n-data) 26%, transparent), transparent 70%);
  filter: blur(52px);
  z-index: -2;
  pointer-events: none;
}

.mockup {
  position: relative;
  border-radius: var(--r-lg);
  border: 1px solid var(--line-2);
  background: var(--card-face);
  box-shadow:
    var(--edge),
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 46px 96px -36px rgba(0, 0, 0, 0.95);
  overflow: hidden;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 420ms var(--ease-out);
  transform-style: preserve-3d;
}

.mockup__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--inset);
}

.mockup__dots { display: flex; gap: 6px; flex-shrink: 0; }
.mockup__dots i {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--line-2);
}
.mockup__dots i:nth-child(1) { background: color-mix(in srgb, var(--n-security) 70%, transparent); }
.mockup__dots i:nth-child(2) { background: color-mix(in srgb, var(--warn) 60%, transparent); }
.mockup__dots i:nth-child(3) { background: color-mix(in srgb, var(--ok) 60%, transparent); }

.mockup__url {
  flex: 1;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.67rem;
  color: var(--ink-4);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.mockup__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ok);
}

.mockup__badge::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 8px currentColor;
}

.mockup__body { padding: 22px clamp(16px, 3vw, 24px) clamp(18px, 3vw, 22px); }

.mockup__label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 11px;
}

.mockup__field {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--inset);
  box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.35);
  padding: 17px 18px;
  min-height: 64px;
  display: flex;
  align-items: center;
  overflow: hidden;
}

/* Scanning sheen that sweeps the field */
.mockup__field::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 34%;
  background: linear-gradient(100deg, transparent, color-mix(in srgb, var(--accent) 12%, transparent), transparent);
  animation: sweep 4.6s var(--ease) infinite;
  pointer-events: none;
}

@keyframes sweep {
  0%        { transform: translateX(-160%); }
  55%, 100% { transform: translateX(420%); }
}

.mockup__pw {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: clamp(0.82rem, 1.9vw, 1.1rem);
  font-weight: 500;
  letter-spacing: 0.005em;
  word-break: break-all;
  line-height: 1.45;
}

.mockup__pw .d { color: var(--accent); }
.mockup__pw .s { color: var(--accent); opacity: 0.6; }

.mockup__pw .cursor {
  display: inline-block;
  width: 2px;
  height: 1em;
  background: var(--accent);
  vertical-align: -0.14em;
  margin-left: 2px;
  animation: blink 1.05s steps(2, start) infinite;
}

@keyframes blink { 50% { opacity: 0; } }

.mockup__meter { margin-top: 15px; }

.mockup__meter-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.76rem;
  margin-bottom: 8px;
}

.mockup__meter-head b { font-weight: 700; color: var(--ok); }
.mockup__meter-head span { color: var(--ink-3); font-variant-numeric: tabular-nums; }

.mockup__bars { display: flex; gap: 4px; }

.mockup__bars i {
  flex: 1;
  height: 5px;
  border-radius: 3px;
  background: var(--surface-3);
  transition: background 500ms var(--ease), box-shadow 500ms var(--ease);
}

.mockup__bars i.on {
  background: var(--ok);
  box-shadow: 0 0 10px color-mix(in srgb, var(--ok) 45%, transparent);
}

.mockup__foot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 17px;
  padding-top: 15px;
  border-top: 1px solid var(--line);
}

/* ---------- 3. Ticker ---------------------------------------- */

.ticker {
  position: relative;
  border-block: 1px solid var(--line-2);
  /* A recessed band, not a raised one. Mixed from --void so it goes darker
     than the canvas in dark mode and lighter than the paper in light mode —
     the same "cut into the page" read in both. */
  background: color-mix(in srgb, var(--void) 78%, transparent);
  padding-block: 15px;
  overflow: hidden;
  /* No backdrop-filter here — it conflicts with mask-image in some engines */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}

.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker 46s linear infinite;
}

.ticker:hover .ticker__track { animation-play-state: paused; }

@keyframes ticker { to { transform: translateX(-50%); } }

.ticker__set {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

/* Monochrome on purpose. Five coloured labels in a row is what made the
   page read as loud; the icons carry the meaning, the hue stays in the
   cards where it is information rather than decoration. The labels
   themselves are set in the same pure ink as body copy — on the recessed
   band they read as the brightest thing in that strip, which is what
   makes it catch the eye without spending a hue on it. */
.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding-inline: 18px;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
  white-space: nowrap;
}

.ticker__icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--ink-3);
  transition: color var(--t) var(--ease);
}

.ticker__item:hover .ticker__icon { color: var(--hue, var(--accent)); }

.ticker__sep {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--line-3);
  flex-shrink: 0;
}

/* ---------- 4. Shelves --------------------------------------- */

/* One column per category, in a row rather than a grid of cards.
   Each shelf names what belongs on it and then shows the tools as
   tiles, so the column is scanned by mark first and label second.
   Five equal columns means no leftover slot and no card that looks
   like a runt version of its neighbour. */

.shelf-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
}

@media (max-width: 1080px) { .shelf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 760px)  { .shelf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px)  { .shelf-grid { grid-template-columns: minmax(0, 1fr); } }

.shelf {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 22px 20px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 82% at 50% -22%, color-mix(in srgb, var(--hue, var(--accent)) 17%, transparent), transparent 62%),
    var(--card-face);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--t) var(--ease), border-color var(--t) var(--ease),
              box-shadow var(--t) var(--ease);
}

/* Hue hairline across the top edge */
.shelf::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--hue, var(--accent)) 75%, transparent), transparent);
  opacity: 0.85;
}

.shelf:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--hue, var(--accent)) 40%, transparent);
  box-shadow: var(--card-shadow-hover), 0 22px 46px -26px color-mix(in srgb, var(--hue, var(--accent)) 60%, transparent);
}

.shelf__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding-bottom: 18px;
}

.shelf__head h3 {
  font-size: 1.04rem;
  letter-spacing: -0.024em;
  color: var(--ink);
}

.shelf:hover .tile { transform: scale(1.05) rotate(-4deg); }

.shelf__blurb {
  font-size: 0.79rem;
  color: var(--ink-3);
  line-height: 1.5;
}

.shelf__tools {
  display: grid;
  gap: 7px;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.shelf__tool {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-2);
  transition: color var(--t-fast) var(--ease);
}

.shelf__tool:hover { color: var(--ink); }

.shelf__icon {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border-radius: 9px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink-3);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}

.shelf__icon svg { width: 14px; height: 14px; }

.shelf__tool:hover .shelf__icon {
  color: var(--hue, var(--accent));
  border-color: color-mix(in srgb, var(--hue, var(--accent)) 38%, transparent);
  background: color-mix(in srgb, var(--hue, var(--accent)) 12%, transparent);
}

.shelf__name { min-width: 0; }

/* ---------- 5. Bento ----------------------------------------- */

.bento {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: minmax(200px, auto);
  gap: 14px;
}

.bento__item { display: flex; }

.bento__item--wide  { grid-column: span 2; }
.bento__item--large { grid-column: span 2; grid-row: span 2; }

@media (max-width: 1040px) {
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bento__item--large { grid-row: span 1; }
}

@media (max-width: 660px) {
  .bento { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
  .bento__item--wide, .bento__item--large { grid-column: span 1; }
}

.tool-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: clamp(20px, 2.3vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background:
    radial-gradient(130% 90% at 12% -18%, color-mix(in srgb, var(--hue, var(--accent)) 15%, transparent), transparent 60%),
    var(--card-face);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--t) var(--ease), border-color var(--t) var(--ease),
              box-shadow var(--t) var(--ease);
}

/* Hue hairline */
.tool-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--hue, var(--accent)) 70%, transparent), transparent 62%);
  opacity: 0.7;
  transition: opacity var(--t) var(--ease);
}

/* Cursor spotlight */
.tool-card::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 0%),
              color-mix(in srgb, var(--hue, var(--accent)) 17%, transparent), transparent 62%);
  opacity: 0;
  transition: opacity var(--t) var(--ease);
  pointer-events: none;
  z-index: -1;
}

.tool-card:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--hue, var(--accent)) 38%, transparent);
  box-shadow: var(--card-shadow-hover), 0 24px 56px -26px color-mix(in srgb, var(--hue, var(--accent)) 52%, transparent);
}

.tool-card:hover::before { opacity: 1; }
.tool-card:hover::after  { opacity: 1; }

.tool-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 16px;
}

.tool-card:hover .tile { transform: scale(1.07) rotate(-5deg); }

.tool-card h3 {
  font-size: clamp(1.06rem, 1.7vw, 1.26rem);
  letter-spacing: -0.026em;
  margin-bottom: 8px;
}

.tool-card p {
  font-size: 0.855rem;
  color: var(--ink-2);
  line-height: 1.6;
  max-width: 46ch;
}

.tool-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 15px;
}

.tool-card__cta {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: auto;
  padding-top: 18px;
  font-size: 0.845rem;
  font-weight: 700;
  color: color-mix(in srgb, var(--hue, var(--accent)) 86%, var(--ink));
}

.tool-card__cta svg { width: 15px; height: 15px; transition: transform var(--t) var(--ease); }
.tool-card:hover .tool-card__cta svg { transform: translateX(4px); }

.tool-card__link {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
}

.tool-card__link:focus-visible { outline-offset: 4px; }

/* --- In-card demo: shared frame --- */
.demo {
  margin-top: 16px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--inset);
  box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.3);
  overflow: hidden;
}

/* Live password sample */
.tool-card__sample {
  padding: 14px 15px;
  font-family: var(--font-mono);
  font-size: clamp(0.74rem, 1.4vw, 0.86rem);
  letter-spacing: 0.005em;
  word-break: break-all;
  line-height: 1.55;
  color: var(--ink-2);
}

.tool-card__sample .d { color: var(--hue, var(--accent)); }
.tool-card__sample .s { color: var(--hue, var(--accent)); opacity: 0.62; }

.tool-card__sample-bar {
  display: flex;
  gap: 4px;
  padding: 0 15px 14px;
}

.tool-card__sample-bar i {
  flex: 1;
  height: 4px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--hue, var(--accent)) 78%, transparent);
  box-shadow: 0 0 9px color-mix(in srgb, var(--hue, var(--accent)) 45%, transparent);
}

.tool-card__sample-bar i:last-child { background: var(--surface-3); box-shadow: none; }

/* The large tile lets its demo absorb the leftover height */
.bento__item--large .demo {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  justify-content: center;
  margin-bottom: 2px;
}

/* Mini before/after "photo" */
.demo__photo {
  position: relative;
  height: 108px;
  background:
    radial-gradient(58% 80% at 22% 26%, color-mix(in srgb, var(--hue, var(--accent)) 62%, transparent), transparent 70%),
    radial-gradient(52% 74% at 78% 72%, color-mix(in srgb, var(--n-data) 46%, transparent), transparent 72%),
    linear-gradient(150deg, color-mix(in srgb, var(--hue, var(--accent)) 18%, transparent), transparent 60%),
    var(--solid);
}

/* Scanline texture, so it reads as an image rather than a flat box */
.demo__photo::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 7px);
  opacity: 0.6;
}

.demo__photo::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: 58%;
  width: 1px;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 12px rgba(0, 0, 0, 0.5);
}

.demo__handle {
  position: absolute;
  top: 50%; left: 58%;
  width: 24px; height: 24px;
  margin: -12px 0 0 -12px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.85);
  background: rgba(10, 10, 14, 0.6);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: grid;
  place-items: center;
  z-index: 2;
}

.demo__handle svg { width: 12px; height: 12px; color: #fff; }

.demo__tags {
  position: absolute;
  inset: auto 10px 10px 10px;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.demo__tags span {
  padding: 2px 7px;
  border-radius: var(--r-pill);
  background: rgba(8, 8, 12, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Mini colour palette */
.demo__swatches {
  display: flex;
  height: 96px;
}

.demo__swatches i {
  flex: 1;
  transition: flex var(--t) var(--ease);
}

.tool-card:hover .demo__swatches i { flex: 1.35; }
.tool-card:hover .demo__swatches i:nth-child(3) { flex: 2.4; }

/* Mini code block */
.demo__code {
  padding: 13px 15px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.75;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
}

.demo__code b { font-weight: 500; color: var(--hue, var(--accent)); }
.demo__code em { font-style: normal; color: var(--ink-2); }

/* Mini diff */
.demo__diff {
  padding: 10px 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.9;
}

.demo__diff span {
  display: block;
  padding-inline: 14px;
  white-space: pre;
  overflow: hidden;
  text-overflow: ellipsis;
}

.demo__diff .del {
  background: color-mix(in srgb, var(--danger) 13%, transparent);
  color: color-mix(in srgb, var(--danger) 90%, var(--ink));
  box-shadow: inset 2px 0 0 var(--danger);
}

.demo__diff .add {
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  color: color-mix(in srgb, var(--ok) 90%, var(--ink));
  box-shadow: inset 2px 0 0 var(--ok);
}

.demo__diff .ctx { color: var(--ink-4); }

/* Everything-else tile. The bento shows five tools properly; this is the
   door to the other fifteen, named rather than counted. */
.bento__all {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: clamp(24px, 2.6vw, 32px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background:
    radial-gradient(80% 100% at 0% 100%, var(--accent-soft), transparent 68%),
    var(--card-face);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--t) var(--ease), border-color var(--t) var(--ease),
              box-shadow var(--t) var(--ease);
}

.bento__all:hover {
  transform: translateY(-4px);
  border-color: var(--line-2);
  box-shadow: var(--card-shadow-hover);
}

.bento__all > svg { width: 22px; height: 22px; color: var(--accent); }

.bento__all b {
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.bento__all .bento__all span,
.bento__all > span {
  font-size: 0.82rem;
  line-height: 1.72;
  color: var(--ink-3);
}

.bento__all em {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  font-style: normal;
  font-size: 0.83rem;
  font-weight: 600;
  color: var(--accent);
}

.bento__all em svg { width: 15px; height: 15px; transition: transform var(--t) var(--ease); }
.bento__all:hover em svg { transform: translateX(4px); }

/* --- Cards without a CTA row --------------------------------- *
   The two small cards name their tool and stop. Nothing repeats
   under them, so the arrow moves up into the head and the whole
   card stays the link it already was. */

.tool-card__aside { display: flex; align-items: center; gap: 9px; }

.tool-card__go {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--ink-3);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease),
              color var(--t) var(--ease), border-color var(--t) var(--ease);
}

.tool-card__go svg { width: 14px; height: 14px; }

.tool-card:hover .tool-card__go,
.tool-card:focus-within .tool-card__go {
  opacity: 1;
  transform: none;
  color: var(--hue, var(--accent));
  border-color: color-mix(in srgb, var(--hue, var(--accent)) 40%, transparent);
}

/* --- Readouts ------------------------------------------------- *
   One line each, under the demo, naming the thing that card's
   tool exists to produce. */

.demo__readout {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-3);
}

.demo__readout b {
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
}

.demo__status {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 12px;
  font-size: 0.73rem;
  font-weight: 500;
  color: var(--ink-3);
}

.demo__status svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--accent); }

/* ---------- 6. Standfirst band -------------------------------- */

/* A statement set at display scale, with nothing around it — no card,
   no border, no icon. It exists to break the run of card sections and
   give the page one moment of plain typography. */

.standfirst {
  padding-block: clamp(48px, 8vw, 104px);
  text-align: center;
}

.standfirst blockquote {
  max-width: 22ch;
  margin-inline: auto;
  font-family: var(--font-display);
  font-weight: 550;
  font-size: clamp(1.75rem, 4.6vw, 3.15rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}

.standfirst blockquote em { font-style: italic; color: var(--accent); }

.standfirst figcaption {
  margin-top: 22px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
}

/* ---------- 7. Jobs (worked examples) ------------------------ */

/* Three cards, each a job rather than a tool. The steps inside are
   the tools, in the order they have to be opened, each with the
   reason it sits where it does. */

.jobs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

@media (max-width: 980px) { .jobs { grid-template-columns: minmax(0, 1fr); } }

.job {
  display: flex;
  flex-direction: column;
  padding: clamp(22px, 2.4vw, 28px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--card-face);
  box-shadow: var(--card-shadow);
}

/* The number is the only orange on the card, and it belongs to the
   bench rather than to any one category — a job crosses drawers. */
.job__num {
  margin-bottom: 12px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.job h3 {
  font-size: 1.12rem;
  letter-spacing: -0.022em;
  margin-bottom: 10px;
}

.job > p {
  font-size: 0.855rem;
  color: var(--ink-2);
  line-height: 1.62;
  /* Keeps a minimum gap above the step list once it is bottom-anchored. */
  margin-bottom: 20px;
}

/* Bottom-anchored so the three step lists line up across the row even
   when the paragraphs above them run to different depths. */
.job__steps {
  list-style: none;
  margin: auto 0 0;
  padding: 0;
  display: grid;
  border-top: 1px solid var(--line);
}

.job__steps li { display: flex; }

.job__step {
  display: grid;
  gap: 3px;
  width: 100%;
  padding: 12px 4px 12px 0;
  border-bottom: 1px solid var(--line);
  transition: padding-left var(--t) var(--ease);
}

.job__step:hover { padding-left: 10px; }

.job__steps li:last-child .job__step {
  padding-bottom: 0;
  border-bottom: 0;
}

.job__step-name {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
  transition: color var(--t-fast) var(--ease);
}

.job__step:hover .job__step-name { color: var(--accent); }

.job__step-note {
  font-size: 0.78rem;
  color: var(--ink-3);
  line-height: 1.5;
}

/* ---------- 8. Limits ---------------------------------------- */

/* A definition list, because that is what it is: the tool, and the
   point past which it stops being worth trusting. */

.limits {
  margin: 0;
  border-top: 1px solid var(--line);
}

.limit {
  display: grid;
  grid-template-columns: minmax(0, 15ch) minmax(0, 1fr);
  gap: clamp(16px, 3vw, 44px);
  padding: clamp(20px, 2.4vw, 28px) 4px;
  border-bottom: 1px solid var(--line);
  transition: background var(--t) var(--ease), padding-left var(--t) var(--ease);
}

.limit:hover { background: var(--surface); padding-left: 16px; }

.limit__what {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.limit__body {
  margin: 0;
  max-width: 72ch;
  font-size: 0.875rem;
  color: var(--ink-2);
  line-height: 1.68;
}

@media (max-width: 700px) {
  .limit { grid-template-columns: minmax(0, 1fr); gap: 8px; }
}

.limits__foot {
  margin-top: 22px;
  font-size: 0.82rem;
  color: var(--ink-3);
}

.limits__foot a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.limits__foot a:hover { color: var(--accent); }

/* ---------- 9. Lookalikes ------------------------------------ */

/* Two tools, one question, one paragraph saying which is which.
   The pair shares a hue because the confusion only happens inside
   a category — nobody mixes up a favicon with a UUID. */

.looks {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

@media (max-width: 820px) { .looks { grid-template-columns: minmax(0, 1fr); } }

.look {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(20px, 2.3vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background:
    radial-gradient(130% 90% at 12% -18%, color-mix(in srgb, var(--hue, var(--accent)) 13%, transparent), transparent 60%),
    var(--card-face);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  isolation: isolate;
}

.look::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--hue, var(--accent)) 70%, transparent), transparent 62%);
  opacity: 0.7;
}

.look h3 {
  font-size: 1.08rem;
  letter-spacing: -0.024em;
  margin-bottom: 16px;
}

.look__sides {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

@media (max-width: 460px) { .look__sides { grid-template-columns: minmax(0, 1fr); } }

.look__side {
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--inset);
}

.look__tool {
  margin-bottom: 5px;
  font-size: 0.8rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--hue, var(--accent)) 82%, var(--ink));
}

.look__what {
  font-size: 0.78rem;
  color: var(--ink-3);
  line-height: 1.55;
}

.look__pick {
  margin-top: 16px;
  padding-top: 15px;
  border-top: 1px solid var(--line);
  font-size: 0.83rem;
  color: var(--ink-2);
  line-height: 1.62;
}

/* ---------- 10. Principles (features) ------------------------ */

.principles {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--line);
}

.principle {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: clamp(16px, 3vw, 34px);
  padding: clamp(24px, 3vw, 34px) 4px;
  border-bottom: 1px solid var(--line);
  transition: background var(--t) var(--ease), padding-left var(--t) var(--ease);
}

.principle:hover { background: var(--surface); padding-left: 16px; }

.principle__body { max-width: 68ch; }
.principle__body h3 { font-size: clamp(1.02rem, 1.6vw, 1.2rem); margin-bottom: 7px; }

.principle__body p {
  font-size: 0.875rem;
  color: var(--ink-2);
  line-height: 1.65;
}

.principle:hover .tile { transform: scale(1.05) rotate(-4deg); }

/* ---------- 11. Build log ------------------------------------ */

/* Copy on the left, the build's own output on the right. The log is
   the receipt for the paragraph beside it — if the claim is wrong,
   the panel is where a reader would catch it. */

.build {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.82fr);
  gap: clamp(26px, 4vw, 64px);
  align-items: start;
}

@media (max-width: 900px) { .build { grid-template-columns: minmax(0, 1fr); } }

.build__copy { max-width: 62ch; }
.build__copy .eyebrow { margin-bottom: 14px; }
.build__copy h2 { margin-bottom: 18px; }

.build__copy p {
  font-size: 0.9rem;
  color: var(--ink-2);
  line-height: 1.72;
}

.build__copy p + p { margin-top: 14px; }

.build__log {
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--inset);
}

.log-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.755rem;
  line-height: 1.5;
}

.log-line:first-child { padding-top: 0; }
.log-line:last-child { padding-bottom: 0; border-bottom: 0; }

.log-line__step { color: var(--ink); }

/* The first line is the command that was typed. */
.log-line:first-child .log-line__step { color: var(--accent); }

.log-line__out { color: var(--ink-3); text-align: right; }

/* ---------- 12. CTA band ------------------------------------- */

.cta-band {
  position: relative;
  border-radius: var(--r-2xl);
  overflow: hidden;
  padding: clamp(46px, 6.5vw, 88px) clamp(24px, 5vw, 64px);
  border: 1px solid var(--line-2);
  background: var(--card-face);
  box-shadow: var(--card-shadow);
  text-align: center;
  isolation: isolate;
}

/* Multi-hue bloom */
.cta-band::before {
  content: '';
  position: absolute;
  inset: -60% -10% auto -10%;
  height: 200%;
  background:
    radial-gradient(34% 40% at 24% 40%, color-mix(in srgb, var(--n-security) 30%, transparent), transparent 70%),
    radial-gradient(34% 40% at 50% 32%, color-mix(in srgb, var(--n-colour) 26%, transparent), transparent 70%),
    radial-gradient(34% 40% at 76% 40%, color-mix(in srgb, var(--n-images) 26%, transparent), transparent 70%);
  filter: blur(34px);
  z-index: -1;
  pointer-events: none;
}

/* A single hairline rule under the type instead of a grid fill —
   the bloom is the texture here. */
.cta-band::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  width: min(420px, 62%);
  height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--accent) 55%, transparent) 50%, transparent);
  pointer-events: none;
}

.cta-band h2 {
  font-size: clamp(2.2rem, 5.6vw, 4rem);
  line-height: 1.02;
}

.cta-band h2 em {
  font-style: italic;
  color: var(--accent);
  padding-right: 0.06em;
}

.cta-band .lede { margin-inline: auto; }

.cta-band__actions {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  flex-wrap: wrap;
  margin-top: 30px;
}

.cta-band__note {
  position: relative;
  margin-top: 20px;
  font-size: 0.76rem;
  color: var(--ink-4);
}

/* ---------- 13. Anatomy (parts of a tool page) ---------------- */

/* No cards here on purpose — the page has had enough of them by
   this point, so the three parts sit directly on the canvas with a
   rule between them. */

.parts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 46px);
}

@media (max-width: 820px) { .parts { grid-template-columns: minmax(0, 1fr); gap: 26px; } }

.part + .part {
  padding-left: clamp(20px, 3vw, 44px);
  border-left: 1px solid var(--line);
}

@media (max-width: 820px) {
  .part + .part {
    padding-left: 0;
    padding-top: 24px;
    border-left: 0;
    border-top: 1px solid var(--line);
  }
}

.part__num {
  display: block;
  margin-bottom: 12px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--accent);
}

.part h3 {
  font-size: 1.1rem;
  letter-spacing: -0.022em;
  margin-bottom: 9px;
}

.part p {
  font-size: 0.86rem;
  color: var(--ink-2);
  line-height: 1.68;
}

.parts__foot {
  margin-top: clamp(28px, 3.5vw, 46px);
  padding-top: clamp(20px, 2.5vw, 28px);
  border-top: 1px solid var(--line);
  max-width: 82ch;
  font-size: 0.86rem;
  color: var(--ink-3);
  line-height: 1.72;
}

/* ---------- 14. Formats -------------------------------------- */

/* The table itself is the shared `.table` component in core.css. All
   that is left here is what is particular to this one: it is the widest
   table on the site and needs a floor under its column widths, and its
   two verdict columns want the shared cell colours. */
.formats { min-width: 580px; }

.formats .table__yes { color: var(--ink); }
.formats .table__no  { color: var(--ink-3); }

/* ---------- 15. Search band ---------------------------------- */

.palette-band {
  display: flex;
  align-items: center;
  gap: clamp(24px, 4vw, 60px);
  padding: clamp(28px, 4vw, 48px) clamp(24px, 4vw, 56px);
  border: 1px solid var(--line-2);
  border-radius: var(--r-2xl);
  background: var(--card-face);
  box-shadow: var(--card-shadow);
}

@media (max-width: 820px) {
  .palette-band { flex-direction: column; align-items: flex-start; gap: 24px; }
}

.palette-band__aside {
  display: grid;
  gap: 12px;
  justify-items: center;
  flex-shrink: 0;
  text-align: center;
}

.palette-band__keys {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.palette-band__hint {
  max-width: 20ch;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  line-height: 1.5;
  color: var(--ink-3);
}

/* Keycaps: a thick bottom edge is what makes them read as keys
   rather than as two small boxes with letters in them. */
.palette-band__keys kbd {
  display: inline-grid;
  place-items: center;
  min-width: 60px;
  height: 60px;
  padding: 0 15px;
  border: 1px solid var(--line-2);
  border-bottom-width: 3px;
  border-radius: 13px;
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink);
}

/* Stacked, the aside is a grid whose widest item is the pair of keycaps,
   so its column is 128px and the hint's own 20ch cap squeezes it to about
   a hundred — a caption wedged sideways under the keys. Above this width
   the cap is doing real work (it stops the hint running the length of the
   band beside tall keycaps); here there is nothing to keep it away from,
   so let it have the line and align the pair left, under the heading.
   These have to come after the two rules above: same specificity, so
   source order is what decides. */
@media (max-width: 820px) {
  .palette-band__aside { justify-items: start; text-align: left; }
  .palette-band__hint { max-width: none; }
}

.palette-band__copy { max-width: 60ch; }

.palette-band__copy h2 {
  font-size: clamp(1.55rem, 3.2vw, 2.4rem);
  margin-bottom: 12px;
}

.palette-band__copy p {
  margin-bottom: 22px;
  font-size: 0.9rem;
  color: var(--ink-2);
  line-height: 1.7;
}

/* ---------- 16. Missing -------------------------------------- */

/* Two columns of short entries, each opening with its own name in
   ink. No cards — this is a list of absences, and dressing it up
   would make it read like a feature. */

.missing {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 clamp(24px, 4vw, 56px);
}

@media (max-width: 760px) { .missing { grid-template-columns: minmax(0, 1fr); } }

.miss {
  padding: 16px 0;
  border-top: 1px solid var(--line);
  font-size: 0.86rem;
  color: var(--ink-3);
  line-height: 1.68;
}

.miss b { font-weight: 600; color: var(--ink); }

/* ---------- 17. Blog band ------------------------------------ */

/* Homepage-only, so it does not live in blog.css. The shape is a card
   with a coloured rule along the top instead of a cover image: three of
   these sit in a row and a cover at this width would be a stamp. The rule
   grows on hover, which is the whole interaction. */
.blog-band {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: 16px;
}

.blog-band__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px 22px 22px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card-face);
  box-shadow: var(--card-shadow);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  transition: border-color var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

.blog-band__item::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: var(--hue, var(--accent));
  transform: scaleX(0.22);
  transform-origin: left;
  transition: transform 320ms var(--ease);
}

.blog-band__item:hover {
  border-color: var(--line-3);
  box-shadow: var(--card-shadow-hover);
  transform: translateY(-2px);
}

.blog-band__item:hover::before { transform: scaleX(1); }

.blog-band__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.blog-band__meta time { color: var(--ink-3); font-variant-numeric: tabular-nums; }

.blog-band__cat { color: var(--hue, var(--accent)); }

.blog-band__title {
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-wrap: balance;
}

.blog-band__title em {
  font-style: italic;
  color: var(--accent);
}

.blog-band__text {
  font-size: 0.88rem;
  line-height: 1.68;
  color: var(--ink-3);
}

.blog-band__go {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: auto;
  padding-top: 14px;
  white-space: nowrap;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-2);
  transition: color var(--t-fast) var(--ease);
}

/* The reset makes every svg a block box with no intrinsic size, so the
   one in here has to be measured explicitly. */
.blog-band__go svg {
  width: 15px;
  height: 15px;
  flex: none;
  transition: transform 220ms var(--ease);
}

.blog-band__item:hover .blog-band__go { color: var(--accent); }
.blog-band__item:hover .blog-band__go svg { transform: translateX(3px); }

/* ---------- 18. Motion preferences --------------------------- */

@media (prefers-reduced-motion: reduce) {
  .ticker__track,
  .mockup__field::after { animation: none; }
  .mockup { transition: none; }
}
