/* ==========================================================================
   SiliCore — components.css
   Cards, badges, timeline, team cards, blog cards, prose, tables, contact.
   ========================================================================== */

/* ========= Generic card ========= */
.card{
  display:flex;flex-direction:column;gap:10px;
  padding:clamp(16px, 2.2vw, 22px);
  background:var(--surface);
  border:1px solid var(--hairline);
  border-radius:var(--radius);
  box-shadow:var(--shadow);
  color:inherit;
  transition:transform var(--speed) var(--ease),
             border-color var(--speed) var(--ease),
             box-shadow var(--speed) var(--ease);
}
a.card:hover{
  transform:translateY(-4px);
  border-color:var(--cyan);
  box-shadow:var(--shadow-cyan);
  color:inherit;
}
a.card:hover .cta svg{transform:translateX(3px)}
.card h3{margin:0}
.card p{color:var(--muted)}
.card__row{display:flex;align-items:center;justify-content:space-between;gap:12px}

.bullets{margin:4px 0 10px;padding-left:18px;color:var(--white);font-size:15px}
.bullets li{margin:5px 0}

/* Thumbnail on blog/topic cards */
.card__thumb{
  width:100%;
  aspect-ratio:16/10;
  object-fit:cover;
  border-radius:var(--radius-sm);
  border:1px solid var(--hairline);
  background:var(--surface-solid);
}

/* ========= Blog cards ========= */
.post-card__meta{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  color:var(--muted);font-size:13px;
}
.post-card__meta time{color:var(--muted)}

/* ========= Team cards ========= */
.member{
  display:flex;flex-direction:column;
  padding:18px;
  text-align:center;
  color:inherit;
  background:var(--surface);
  border:1px solid var(--hairline);
  border-radius:var(--radius);
  box-shadow:var(--shadow);
  transition:transform var(--speed) var(--ease),
             border-color var(--speed) var(--ease),
             box-shadow var(--speed) var(--ease);
}
.member:hover{
  transform:translateY(-4px);
  border-color:var(--cyan);
  box-shadow:0 0 24px rgba(24,224,255,.20);
  color:inherit;
}
.member__photo{
  width:100%;
  aspect-ratio:1/1;
  object-fit:cover;
  border-radius:14px;
  border:1px solid var(--hairline);
  margin-bottom:14px;
  background:var(--surface-solid);
}
.member h3{margin:0 0 4px}
.member__role{
  display:block;
  color:var(--cyan);
  font-size:14px;font-weight:600;
  margin-bottom:10px;
}
.member__facts{
  list-style:none;
  text-align:left;
  color:var(--muted);
  font-size:14px;
}
.member__facts li{
  position:relative;
  padding-left:16px;
  margin:6px 0;
}
.member__facts li::before{
  content:"";
  position:absolute;left:0;top:.6em;
  width:5px;height:5px;border-radius:50%;
  background:var(--cyan);opacity:.7;
}

/* Team lead gets a persistent cyan edge rather than a layout offset.
   (The old design nudged the card up 80px, which broke on every reflow.) */
.member--lead{
  border-color:rgba(24,224,255,.45);
  box-shadow:0 0 28px rgba(24,224,255,.16);
}

/* Initials avatar — placeholder until a real photo is dropped in */
.avatar-initials{
  width:100%;
  aspect-ratio:1/1;
  border-radius:14px;
  border:1px solid var(--hairline);
  margin-bottom:14px;
  display:grid;place-items:center;
  background:
    radial-gradient(circle at 50% 35%, rgba(24,224,255,.20), transparent 62%),
    var(--surface-solid);
  color:var(--cyan);
  font-size:clamp(32px, 6vw, 52px);
  font-weight:800;
  letter-spacing:2px;
}

/* ========= Timeline =========
   Two swimlanes ("tracks") sharing a visual language. Nodes carry two
   independent axes:
     weight  — .node--major (headline milestone) / .node--minor (interim tick)
     status  — .is-done / .is-current / .is-upcoming
   These compose: demo_v08 is major AND current, so it is the loudest node. */

.timeline{display:grid;gap:clamp(32px, 5vw, 56px)}

.track{
  padding:clamp(18px, 2.6vw, 26px);
  background:var(--surface);
  border:1px solid var(--hairline);
  border-radius:var(--radius);
}
.track__head{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;flex-wrap:wrap;
  margin-bottom:clamp(28px, 4vw, 40px);
}
.track__label{
  font-size:13px;font-weight:700;
  letter-spacing:1.6px;text-transform:uppercase;
  color:var(--cyan);
}
.track__meta{color:var(--muted);font-size:13px}

/* --- The rail (horizontal on desktop) --- */
.track__rail{
  list-style:none;
  display:flex;
  align-items:flex-start;
}

.node{
  position:relative;
  padding-top:38px;          /* room for the dot row above the body */
  text-align:center;
  min-width:0;
}
.node--major{flex:1.7 1 0}
.node--minor{flex:.75 1 0}

/* Connector: the line into a node is drawn in two halves — the right half of
   the node before it (::after) plus that node's own left half (::before). Two
   halves rather than one segment because neighbouring nodes have different
   widths (major 1.7fr, minor .75fr), so no single offset reaches the previous
   node's dot. */
.node::before,
.node::after{
  content:"";
  position:absolute;
  top:13px;
  border-top:2px solid rgba(24,224,255,.45);
}
.node::before{left:0;right:50%}
.node::after{left:50%;right:0}
.node:first-child::before{display:none}
.node:last-child::after{display:none}

/* Everything past the current milestone is speculative — draw it dashed.
   A node's ::after leads into the *next* node, so it takes that node's
   status rather than its own. */
.node.is-upcoming::before,
.node.is-upcoming::after,
.node:has(+ .node.is-upcoming)::after{
  border-top-style:dashed;
  border-top-color:rgba(168,179,199,.45);
}

/* --- Dots --- */
.node__dot{
  position:absolute;
  top:14px;
  left:50%;
  transform:translate(-50%, -50%);
  border-radius:50%;
  background:var(--cyan);
  z-index:1;
}
.node--major .node__dot{
  width:18px;height:18px;
  box-shadow:0 0 0 4px rgba(24,224,255,.16), 0 0 16px rgba(24,224,255,.5);
}
.node--minor .node__dot{
  width:9px;height:9px;
  background:rgba(168,179,199,.85);
  box-shadow:0 0 0 3px rgba(10,18,40,.9);
}
.node.is-upcoming .node__dot{
  background:transparent;
  border:2px solid rgba(168,179,199,.7);
  box-shadow:none;
}
.node--major.is-upcoming .node__dot{width:16px;height:16px}

/* Current milestone pulses. Strongest treatment on the page. */
.node.is-current .node__dot{
  background:var(--cyan);
  animation:node-pulse 2.4s var(--ease) infinite;
}
@keyframes node-pulse{
  0%  {box-shadow:0 0 0 0 rgba(24,224,255,.5),  0 0 18px rgba(24,224,255,.65)}
  70% {box-shadow:0 0 0 16px rgba(24,224,255,0), 0 0 18px rgba(24,224,255,.65)}
  100%{box-shadow:0 0 0 0 rgba(24,224,255,0),   0 0 18px rgba(24,224,255,.65)}
}

/* --- Node body --- */
.node__body{padding-inline:8px}

.node__date{
  display:inline-block;
  margin-bottom:8px;
  font-size:11px;
  padding:3px 9px;
}
.node__title{
  margin:0;
  font-size:15px;
  font-weight:700;
  line-height:1.3;
  overflow-wrap:anywhere;
}
.node__blurb{
  margin-top:6px;
  color:var(--muted);
  font-size:13px;
  line-height:1.45;
}

.node--major.is-current .node__title{color:var(--cyan)}

/* Minor nodes: version label only, blurb revealed on hover/focus.
   The blurb is absolutely positioned so revealing it never reflows the rail. */
.node--minor .node__title{
  font-size:12px;
  font-weight:600;
  color:var(--muted);
}
.node--minor .node__blurb{
  position:absolute;
  left:50%;
  transform:translateX(-50%) translateY(4px);
  top:calc(100% + 2px);
  z-index:3;
  width:max-content;
  max-width:180px;
  padding:8px 11px;
  background:#0a1228;
  border:1px solid var(--hairline-strong);
  border-radius:10px;
  box-shadow:var(--shadow);
  color:var(--white);
  font-size:12px;
  opacity:0;
  pointer-events:none;
  transition:opacity var(--speed) var(--ease), transform var(--speed) var(--ease);
}
.node--minor:hover .node__blurb,
.node--minor:focus-visible .node__blurb{
  opacity:1;
  transform:translateX(-50%) translateY(0);
}
.node--minor:hover .node__title,
.node--minor:focus-visible .node__title{color:var(--white)}
.node--minor:hover .node__dot{background:var(--cyan)}

/* --- Mobile: rail becomes a vertical list --- */
@media (max-width: 820px){
  .track__rail{display:block}

  .node{
    padding-top:0;
    padding-left:34px;
    padding-bottom:22px;
    text-align:left;
  }
  .node:last-child{padding-bottom:0}

  /* Vertical rail: each ::before already spans the node's full height, so the
     desktop right-half segment is not needed. */
  .node::after{display:none}

  /* Connector runs vertically down the left gutter. */
  .node::before{
    top:0;bottom:0;
    left:8px;right:auto;
    width:0;
    border-top:0;
    border-left:2px solid rgba(24,224,255,.45);
  }
  .node:first-child::before{display:block;top:10px}
  .node:last-child::before{bottom:auto;height:12px}
  .node.is-upcoming::before{
    border-left-style:dashed;
    border-left-color:rgba(168,179,199,.45);
  }

  .node__dot{
    top:10px;
    left:9px;
    transform:translate(-50%, 0);
  }

  .node__body{
    padding-inline:0;
    display:flex;flex-direction:column;align-items:flex-start;
  }
  .node--major .node__body{gap:2px}

  /* Minor rows collapse to a single compact line with the blurb inline —
     no hover on touch, so the tooltip becomes static text. */
  .node--minor{padding-bottom:14px}
  .node--minor .node__blurb{
    position:static;
    transform:none;
    opacity:1;
    /* It is plain static text here, not a popover — nothing to animate, and
       leaving the transition on means a resize can catch it mid-fade. */
    transition:none;
    pointer-events:auto;
    max-width:none;
    padding:0;
    background:none;
    border:0;
    box-shadow:none;
    color:var(--muted);
    font-size:12px;
    margin-top:2px;
  }
}

/* noscript fallback for the timeline */
.timeline-fallback{
  display:grid;gap:24px;
}
.timeline-fallback ol{
  list-style:none;
  border-left:2px solid rgba(24,224,255,.4);
  padding-left:18px;
}
.timeline-fallback li{margin-bottom:12px}
.timeline-fallback strong{color:var(--white)}

/* ========= Prose (blog posts, about, architecture) ========= */
.prose{color:var(--white)}
.prose > * + *{margin-top:1.1em}
.prose h2{
  margin-top:2em;
  padding-bottom:.35em;
  border-bottom:1px solid var(--hairline);
}
.prose h3{margin-top:1.6em}
.prose p,.prose li{color:#dfe6f2;font-size:clamp(15px,1.9vw,17px)}
.prose ul,.prose ol{padding-left:22px}
.prose li{margin:.45em 0}
.prose img{
  border-radius:var(--radius-sm);
  border:1px solid var(--hairline);
  margin-block:1.4em;
}
.prose figure{margin:1.6em 0}
.prose figcaption{
  margin-top:10px;
  color:var(--muted);
  font-size:13px;
  text-align:center;
}
.prose code{
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:.9em;
  padding:2px 6px;
  border-radius:6px;
  background:rgba(24,224,255,.10);
  border:1px solid rgba(24,224,255,.20);
  color:var(--cyan);
}
.prose pre{
  overflow-x:auto;
  padding:16px 18px;
  border-radius:var(--radius-sm);
  background:#08101f;
  border:1px solid var(--hairline);
}
.prose pre code{background:none;border:0;padding:0;color:#dfe6f2}
.prose blockquote{
  margin:1.6em 0;
  padding:2px 0 2px 18px;
  border-left:3px solid var(--cyan);
  color:var(--muted);
  font-style:italic;
}
.prose hr{border:0;border-top:1px solid var(--hairline);margin:2.2em 0}

/* Callout box — used for "work in progress" notices on scaffold posts */
.callout{
  display:flex;gap:14px;
  padding:16px 18px;
  border-radius:var(--radius-sm);
  border:1px solid rgba(24,224,255,.28);
  background:rgba(24,224,255,.07);
}
.callout__icon{flex:none;font-size:20px;line-height:1.3}
.callout p{margin:0;color:#dfe6f2;font-size:15px}
.callout strong{color:var(--white)}

/* ========= Tables ========= */
.table-wrap{
  overflow-x:auto;
  border:1px solid var(--hairline);
  border-radius:var(--radius-sm);
  margin-block:1.4em;
}
table{
  width:100%;
  border-collapse:collapse;
  font-size:15px;
  min-width:520px;
}
thead th{
  text-align:left;
  padding:12px 16px;
  background:rgba(24,224,255,.08);
  color:var(--white);
  font-size:13px;
  letter-spacing:.6px;
  text-transform:uppercase;
  border-bottom:1px solid var(--hairline);
  white-space:nowrap;
}
tbody td{
  padding:12px 16px;
  border-bottom:1px solid rgba(255,255,255,.05);
  color:#dfe6f2;
  vertical-align:top;
}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover td{background:rgba(255,255,255,.02)}
td .mono,td code{white-space:nowrap}

/* ========= Contact ========= */
.contact-box{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--gap);flex-wrap:wrap;
  padding:clamp(18px, 2.4vw, 26px);
  border:1px solid var(--hairline-strong);
  border-radius:var(--radius);
  background:linear-gradient(180deg, rgba(12,26,58,.6), rgba(12,26,58,.35));
  box-shadow:var(--shadow);
}
.contact-box__email{
  font-weight:700;
  font-size:clamp(15px, 2.2vw, 19px);
  color:var(--white);
  padding:10px 14px;
  border-radius:10px;
  border:1px dashed var(--hairline-strong);
}
.contact-box__email:hover{color:var(--cyan);border-color:var(--cyan)}
.copy-btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:10px 14px;
  border-radius:var(--radius-sm);
  border:1px solid var(--hairline-strong);
  background:rgba(255,255,255,.06);
  font-weight:600;
  cursor:pointer;
  transition:border-color var(--speed) var(--ease);
}
.copy-btn:hover{border-color:var(--cyan)}
.copy-btn svg{width:16px;height:16px;flex:none}

/* ========= Stat strip ========= */
.stats{
  display:grid;
  gap:var(--gap);
  grid-template-columns:repeat(auto-fit, minmax(min(100%, 160px), 1fr));
}
.stat{
  padding:18px;
  border-radius:var(--radius-sm);
  border:1px solid var(--hairline);
  background:var(--surface);
  text-align:center;
}
.stat__value{
  display:block;
  font-size:clamp(22px, 3.4vw, 30px);
  font-weight:800;
  color:var(--cyan);
  line-height:1.1;
}
.stat__label{
  display:block;
  margin-top:6px;
  color:var(--muted);
  font-size:13px;
}

/* ========= Post navigation (prev/next) ========= */
.post-nav{
  display:grid;
  gap:var(--gap);
  grid-template-columns:repeat(2, minmax(0,1fr));
  margin-top:clamp(40px, 6vw, 64px);
  padding-top:28px;
  border-top:1px solid var(--hairline);
}
@media (max-width: 640px){
  .post-nav{grid-template-columns:1fr}
}
.post-nav a{
  display:flex;flex-direction:column;gap:4px;
  padding:16px 18px;
  border-radius:var(--radius-sm);
  border:1px solid var(--hairline);
  background:var(--surface);
  color:inherit;
  transition:border-color var(--speed) var(--ease), transform var(--speed) var(--ease);
}
.post-nav a:hover{border-color:var(--cyan);transform:translateY(-2px);color:inherit}
.post-nav__dir{color:var(--muted);font-size:12px;letter-spacing:1px;text-transform:uppercase}
.post-nav__title{font-weight:600}
.post-nav a:last-child{text-align:right}
.post-nav a:only-child{grid-column:1 / -1}

/* ========= Contributor card (blog sidebar) ========= */
.contributor{
  display:flex;align-items:center;gap:12px;
  margin-top:12px;
  padding:10px;
  border:1px solid var(--hairline);
  border-radius:var(--radius-sm);
  background:var(--surface);
  color:inherit;
  text-decoration:none;
  transition:border-color var(--speed) var(--ease),
             box-shadow var(--speed) var(--ease),
             transform var(--speed) var(--ease);
}
.contributor:hover,
.contributor:focus-visible{
  border-color:var(--cyan);
  box-shadow:0 0 20px rgba(24,224,255,.16);
  transform:translateY(-2px);
  color:inherit;
}
.contributor__photo{
  width:56px;height:56px;flex:none;
  border-radius:50%;
  object-fit:cover;
  border:1px solid var(--hairline);
}
.contributor__text{display:flex;flex-direction:column;gap:2px;min-width:0}
.contributor__name{font-weight:700;font-size:14px;line-height:1.25}
.contributor__role{color:var(--muted);font-size:12px;line-height:1.35}
.contributor__arrow{margin-left:auto;color:var(--cyan);flex:none}
.contributor__arrow svg{width:20px;height:20px;transition:transform var(--speed) var(--ease)}
.contributor:hover .contributor__arrow svg{transform:translateX(3px)}

/* ========= Figure (diagrams outside .prose) ========= */
.figure{margin:0}
.figure img{
  display:block;
  width:100%;
  max-width:760px;
  margin-inline:auto;
  border:1px solid var(--hairline);
  border-radius:var(--radius);
  background:var(--surface-solid);
}
.figure figcaption{
  margin-top:10px;
  color:var(--muted);
  font-size:13px;
  text-align:center;
}

/* ========= Group label (sub-heading inside a section) ========= */
.group-label{
  margin:28px 0 14px;
  font-size:12px;
  font-weight:800;
  letter-spacing:1.6px;
  text-transform:uppercase;
  color:var(--cyan);
}
.group-label:first-of-type{margin-top:0}

/* Implementation rows: a row holding one card must not stretch it to the full
   container width — it should match the width of a card in a paired row. */
.grid--impl > .card{max-width:520px}

/* ========= Competition result banner ========= */
.result{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:clamp(16px, 3vw, 28px);
  padding:clamp(18px, 3vw, 28px);
  border:1px solid rgba(24,224,255,.35);
  border-radius:var(--radius);
  background:
    linear-gradient(180deg, rgba(24,224,255,.10), rgba(24,224,255,.03)),
    var(--surface-solid);
  box-shadow:var(--shadow-cyan);
}
.result__rank{
  flex:none;
  font-size:clamp(40px, 7vw, 64px);
  font-weight:800;
  line-height:1;
  color:var(--cyan);
  letter-spacing:-1px;
}
.result__rank sup{font-size:.45em;top:-.6em;position:relative}
.result__title{
  margin:0 0 4px;
  font-size:clamp(17px, 2.2vw, 22px);
  line-height:1.25;
}
.result__text p{margin:0;color:var(--muted);font-size:14px;line-height:1.5}

@media (max-width: 560px){
  .result{flex-direction:column;align-items:flex-start;text-align:left}
}

/* Download button inside the result banner. */
.result__dl{
  margin-left:auto;
  flex:0 1 auto;
  max-width:100%;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:10px;
}
.result__dl svg{width:18px;height:18px;flex:none}
.result__dl-meta{font-size:12px;font-weight:600;opacity:.7}
@media (max-width: 860px){
  /* Left-aligned under the text, and allowed to wrap rather than push the
     page sideways — the label is long. */
  .result__dl{margin-left:0;flex-wrap:wrap}
}
