/* ============================================================
   LINKS & BUTTONS — single source of truth for every clickable
   text element on the site.

   Vocabulary (design system v2, see assets/tokens.css):
     display font, 700, UPPERCASE, on a soft pill with a dashed
     hairline border and 8px radius — the rule goes solid and the
     fill lifts on hover. Nav pills and in-text buttons
     share the box but not the ink: nav rests at --ink-faint and
     lifts to --ink-strong, buttons sit at the dimmer --ink-btn.
     Only .bio-project-link stays body-size running text.

   Selectors covered:
     • nav menu .....  .combined-menu a   (+ .link-text / .year)
     • in-text pill ..  .bio-link (inline) , .bio-case-link (block)
     • in-text text ..  .bio-project-link  (underline only, no pill)
     • tool buttons ..  .action-btn , .evenit-action-btn

   NB: the nav-menu DOM is generated by dist/core.bundle.js, so we
   target the existing selectors rather than a single shared class.
   Menu CONTAINER layout stays in combined-menu.css; non-link bio
   text styles stay in bio-text.css.
   ============================================================ */

/* ---- TEXT: every pill label wears the display style ----
   Nav rows and in-text buttons are the same type now; only the resting ink
   tells them apart. */
.bio-link,
.bio-case-link,
.action-btn,
.evenit-action-btn,
.combined-menu a .link-text,
.combined-menu a .year {
  font: var(--type-display);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
  text-decoration-line: none;
  transition: color var(--dur-state) ease, text-decoration-color var(--dur-state) ease;
}

.bio-link,
.bio-case-link,
.action-btn,
.evenit-action-btn {
  color: var(--ink-btn);
}

.combined-menu a .link-text,
.combined-menu a .year {
  color: var(--ink-faint);
}

/* ---- UNDERLINE: only in-text project names carry one ---- */
.bio-project-link {
  color: var(--ink);
  font: var(--type-body);
  text-transform: lowercase;
  text-decoration-line: underline;
  text-decoration-color: var(--ink-dim);
  text-decoration-thickness: 7.5%; /* ~0.9px */
  text-underline-offset: 1.6px;
  text-underline-position: auto;
  transition: color var(--dur-state) ease, text-decoration-color var(--dur-state) ease;
}

/* the nav <a> wraps its label in a span — keep the <a> itself un-underlined */
.combined-menu a {
  text-decoration: none;
}

/* ---- PILL: the button box (everything except the plain text-link) ---- */
.combined-menu a,
.bio-link,
.bio-case-link,
.action-btn,
.evenit-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  box-sizing: border-box;
  white-space: nowrap;
  padding: var(--pad-pill);
  border-radius: var(--r-pill);
  border: var(--bw) dashed var(--line-soft);
  /* Opaque, not the translucent --surface it is flattened from. Menu rows
     needed it first — the timeline's dashed rules run BEHIND them, and a
     see-through fill let the dashes read straight through a row and through
     the gaps in its own dashed border — and every pill takes it now, so one
     value decides what a resting button looks like and no pill can be tinted
     by whatever happens to sit under it. On the page ground the two resolve to
     the same colour, so nothing moved the day this changed. The lit state is
     already opaque white, and both ends of the hover fade being solid keeps it
     animating exactly as before. */
  background: var(--surface-solid);
  /* The lit fill stops short of the edge. A 2px ring of the resting colour is
     laid inside the border, so when the background goes white on hover the
     white reads as a panel opening inside the button rather than flooding it —
     the same little frame the index button is drawn as.

     An inset shadow rather than a pseudo-element: it paints above the
     background and below the label, so nothing needs a z-index and the ::after
     gap-reach strips below keep the pseudo-element they already use. It is
     declared in BOTH states and never animates — at rest it is the same colour
     as the fill behind it and so invisible; only the background travels, which
     is what makes the panel appear to open. Its inner corner lands at 5px
     (--r-pill 8, less the 1px rule, less these 2px), which is --r-md, the
     radius the index button's panel was drawn with. */
  box-shadow: inset 0 0 0 2px var(--surface-solid);
  position: relative;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color var(--dur-state) ease, border-color var(--dur-state) ease, color var(--dur-state) ease;
}

/* ---- and the nav column travels ----
   Timeline view slides each menu row right to the year it started — the
   geometry, and the reasoning behind it, live in combined-menu.css. Only the
   transition is
   restated here: that sheet loads FIRST, so a `transition` shorthand written
   there would be wiped out by the pill rule above. --tl-delay is the row's
   place in the cascade, written inline by render(). The colour transitions
   deliberately carry no delay, so hover stays instant however far a row has
   travelled. */
.combined-menu a {
  transition: background-color var(--dur-state) ease,
              border-color var(--dur-state) ease,
              color var(--dur-state) ease,
              margin-left var(--dur-timeline) ease var(--tl-delay, 0s),
              max-width var(--dur-timeline) ease var(--tl-delay, 0s);
}

/* ---- per-context display variants ---- */
/* social links flow inline within running text */
.bio-link {
  vertical-align: baseline;
}

/* case links hug their text; .btn-row is what puts several on one line.
   display:block (over the pill's inline-flex) so text-overflow works — a long
   label like "what is a subscription?" truncates with an ellipsis instead of
   overrunning the column. Case links carry no icon, so nothing needs the flex. */
.bio-case-link {
  display: block;
  width: fit-content;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* a wrapping row of buttons — instagram / telegram / email / … */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--stack-3);
  margin-top: var(--stack-3);
}

/* ---- GAP REACH: the space between two pills belongs to the one before it ----
   Each pill grows an invisible strip exactly one gap wide, laid over the space
   toward its neighbour. Because the strip is a pseudo-element it is part of the
   pill for hit testing, so the gap both keeps the previous pill lit and clicks
   through to it — the reach grows, the drawn pill does not.

   The strip sits past the pill's edge rather than over it, so it never covers
   the label and text selection still works. Sized to the gap exactly: any wider
   and it would swallow the next pill's own hover. */
.combined-menu a:not(:last-of-type)::after,
.btn-row > a:not(:last-child)::after {
  content: "";
  position: absolute;
  background: transparent;
}

/* menu is a column — reach downward */
.combined-menu a:not(:last-of-type)::after {
  left: 0;
  right: 0;
  bottom: calc(-1 * (var(--stack-3) + var(--bw)));
  height: var(--stack-3);
}

/* button rows are horizontal — reach to the right */
.btn-row > a:not(:last-child)::after {
  top: 0;
  bottom: 0;
  right: calc(-1 * (var(--stack-3) + var(--bw)));
  width: var(--stack-3);
}

/* ---- LIT STATE ----
   Figma's menu-item component (2669:1599) has exactly two variants, and its
   "Variant2" is this: the fill lifts to white. The dashed rule only goes solid
   for the nav's CURRENT page (.active), which wears it permanently — hover /
   selection keeps the dashed border and just lifts the fill.

   Menu pills are lit by .is-hovered, NOT by :hover. The bundle resolves the
   pointer to a link once per move and uses that one answer for both the class
   and the preview image, so the two can never disagree — see setupPreview() in
   dist/core.bundle.js. Adding a :hover rule here would put a second, competing
   resolution back in play. Plain buttons carry no preview, so nothing can
   desync and they stay on :hover. */
.combined-menu a.is-hovered,
.combined-menu a.active,
.bio-link:hover,
.bio-case-link:hover,
.action-btn:hover,
.evenit-action-btn:hover {
  background: #ffffff;
  /* dashed rule darkens a step on lit: --line-soft (.14) -> --rule (.20) */
  border-color: black;
}

/* solid border = current page only */
.combined-menu a.active {
  border-style: solid;
}

.bio-link:hover,
.bio-case-link:hover,
.action-btn:hover,
.evenit-action-btn:hover,
.combined-menu a.is-hovered .link-text,
.combined-menu a.is-hovered .year,
.combined-menu a.active .link-text,
.combined-menu a.active .year {
  color: var(--ink-strong);
}

.bio-project-link:hover {
  color: var(--ink-strong);
  text-decoration-color: var(--ink-strong);
}

/* ---- PLAIN TEXT-LINK: project names (freelance previews), no pill ----
   inline-block + nowrap keeps each name on one line; the padding gives
   post-comma spacing and a wrap opportunity between projects. */
.bio-project-link {
  display: inline-block;
  white-space: nowrap;
  padding: 2px 4px 2px 1px;
  margin: -2px -3px -2px 0;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

/* yellow text selection on case links */
.bio-case-link::selection {
  background-color: rgba(255, 208, 0, 0.12);
  color: var(--ink-strong);
}
