/* ==========================================================================
   Portfolio site styles.

   Layered on top of the Scope V2 design tokens in _ds/ — this file only holds
   page composition. Every colour, font, radius and spacing value comes from a
   token; the only hard-coded hex values are the two QueueSee brand colours on
   the menu toggle bars.

   Theme: the tokens declare dark on :root and light under [data-theme="light"].
   assets/site.js stamps data-theme onto <html>. With JS off the page stays on
   the dark default, which is a valid rendering rather than a broken one.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

/* The header is sticky, so in-page jumps must land with the section's top
   edge exactly beneath it: no gap that lets the previous section show
   through. site.js measures the header and keeps --header-h current. */
html {
  scroll-padding-top: var(--header-h, 65px);
}

body {
  min-height: 100vh;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 400;
  text-wrap: pretty;
}

p {
  margin: 0;
  text-wrap: pretty;
}

img {
  max-width: 100%;
  height: auto;
}

/* Groups of chips, cards and nav items are marked up as real lists so they
   are announced as such; none of them want list styling. */
.chips,
.grid,
.site-nav,
.mobile-menu__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */

/* Horizontal gutter shared by every full-width band. */
.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding-inline: clamp(16px, 5vw, 24px);
  box-sizing: border-box;
}

.section {
  border-top: var(--scope-hairline) solid var(--scope-line);
  padding-block: clamp(48px, 8vw, 72px) clamp(56px, 9vw, 88px);
}

.section--tight {
  padding-block: clamp(48px, 8vw, 72px) clamp(52px, 8vw, 80px);
}

.section--plain {
  border-top: 0;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, 20px);
}

.stack--xs {
  --stack-gap: 6px;
}
.stack--sm {
  --stack-gap: 10px;
}
.stack--md {
  --stack-gap: 18px;
}
.stack--lg {
  --stack-gap: 28px;
}
.stack--xl {
  --stack-gap: 40px;
}

/* auto-fit grid; instances tune the track floor and gap via modifiers. */
.grid {
  display: grid;
  gap: var(--grid-gap, 20px);
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--grid-min, 280px), 100%), 1fr)
  );
}

.grid--facts {
  --grid-min: 260px;
}
/* Contact tiles snap between three fixed layouts rather than auto-fitting:
   four across, two by two, then a single column. */
.grid--links {
  --grid-gap: 12px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: 900px;
}

@media (max-width: 779px) {
  .grid--links {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 479px) {
  .grid--links {
    grid-template-columns: minmax(0, 1fr);
  }
}
.grid--skills {
  --grid-min: 230px;
  --grid-gap: 28px;
}
.grid--prose {
  --grid-min: 300px;
  --grid-gap: 48px;
  align-items: start;
}

.grid--pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */

/* Tracked-out uppercase mono — the recurring section and field label. */
.label {
  font-family: var(--scope-font-mono);
  font-size: var(--scope-text-micro-size);
  letter-spacing: var(--scope-text-micro-tracking);
  color: var(--scope-ink-3);
}

.label--accent {
  color: var(--scope-green);
}

/* Kept to one line: the size and tracking shrink with the viewport so the
   full "SOFTWARE ENGINEER · MELBOURNE, AUSTRALIA" fits a 320px phone. */
.eyebrow {
  font-family: var(--scope-font-mono);
  font-size: clamp(9px, 2.8vw, 13px);
  letter-spacing: clamp(1.2px, 0.5vw, 2.4px);
  color: var(--scope-green);
  white-space: nowrap;
}

.meta {
  font-family: var(--scope-font-mono);
  font-size: 11px;
  letter-spacing: var(--scope-text-nav-tracking);
  color: var(--scope-ink-3);
}

.wordmark {
  font-family: var(--scope-font-mono);
  font-size: 13px;
  letter-spacing: 2.2px;
  color: var(--scope-ink-1);
}

.lead {
  font-size: clamp(18px, 2.8vw, 21px);
  line-height: 1.5;
  color: var(--scope-ink-2);
  max-width: 660px;
}

/* Inside a grid column the measure is already constrained by the track. */
.lead--full {
  max-width: none;
}

.prose {
  font-size: 17px;
  line-height: 1.65;
  color: var(--scope-ink-2);
}

.body {
  font-size: 16px;
  line-height: 1.6;
  color: var(--scope-ink-2);
}

.body--narrow {
  max-width: 640px;
}

.note {
  font-size: 15px;
  line-height: 1.6;
  color: var(--scope-ink-2);
}

.title-hero {
  font-size: clamp(40px, 6vw, 68px);
  line-height: 1.06;
  max-width: 900px;
}

.title-section {
  font-size: clamp(25px, 4.4vw, 32px);
  line-height: 1.2;
}

.title-section--cap {
  max-width: 700px;
}

/* Section heading: label, then a hairline that eats the remaining width. */
.rule {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}

/* The hairline is always an explicit element rather than a generated one, so
   a rule can carry a trailing label after it without any :has() gymnastics. */
.rule__line {
  flex: 1;
  height: var(--scope-hairline);
  min-width: 40px;
  background: var(--scope-line);
}

/* --------------------------------------------------------------------------
   Header / navigation
   -------------------------------------------------------------------------- */

.site-header {
  border-bottom: var(--scope-hairline) solid var(--scope-line);
  position: sticky;
  top: 0;
  background: var(--scope-bg-0);
  z-index: 5;
}

.site-header__bar {
  min-height: var(--scope-h-navbar-desktop);
  display: flex;
  align-items: center;
  gap: 10px 24px;
  flex-wrap: wrap;
  padding-block: 12px;
}

.site-header__spacer {
  flex: 1;
  min-width: 0;
}

/* Wide-viewport cluster: section links plus the theme switch. */
.site-header__desktop {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.site-nav__link {
  font-family: var(--scope-font-mono);
  font-size: 11px;
  letter-spacing: var(--scope-text-nav-tracking);
  color: var(--scope-ink-3);
}

.site-nav__link:hover {
  color: var(--scope-green-hi);
}

/* Hamburger / close toggle, shown only on narrow viewports. */
.menu-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: var(--scope-touch-target);
  height: 40px;
  background: var(--scope-bg-1);
  border: var(--scope-hairline) solid var(--scope-line);
  border-radius: var(--scope-radius-sm);
  cursor: pointer;
  padding: 0 10px;
  box-sizing: border-box;
}

.menu-toggle:hover {
  border-color: var(--scope-green);
}

.menu-toggle__bars {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.menu-toggle__bars span {
  height: 3px;
  border-radius: 2px;
}

/* The three bars echo the QueueSee "Queue Q" mark. Its top two bars keep
   their brand colours in both themes, so they are fixed here rather than
   taken from the theme tokens (which darken in light mode); the third bar
   follows the theme's main green exactly as the logo does. */
.menu-toggle__bars span:nth-child(1) {
  width: 20px;
  background: #ffb300;
}
.menu-toggle__bars span:nth-child(2) {
  width: 16px;
  background: #67d06b;
}
.menu-toggle__bars span:nth-child(3) {
  width: 11px;
  background: var(--scope-green);
}

.menu-toggle__close {
  font-family: var(--scope-font-mono);
  font-size: 15px;
  line-height: 1;
  color: var(--scope-green);
}

/* Swap glyphs on open/closed rather than swapping DOM. */
.menu-toggle[aria-expanded="false"] .menu-toggle__close,
.menu-toggle[aria-expanded="true"] .menu-toggle__bars {
  display: none;
}

.mobile-menu {
  border-top: var(--scope-hairline) solid var(--scope-line);
  background: var(--scope-bg-1);
  padding-block: 10px 16px;
}

.mobile-menu__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.mobile-menu__link {
  display: block;
  padding: 14px 10px;
  border-radius: var(--scope-radius-sm);
  font-family: var(--scope-font-mono);
  font-size: 12px;
  letter-spacing: var(--scope-text-nav-tracking);
  color: var(--scope-ink-2);
}

.mobile-menu__link:hover {
  background: var(--scope-bg-2);
  color: var(--scope-ink-1);
}

.mobile-menu__theme {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding: 0 10px;
}

/* Below the breakpoint the inline nav is replaced by the toggle + panel. */
@media (max-width: 779px) {
  .site-header__desktop {
    display: none;
  }
}

@media (min-width: 780px) {
  .menu-toggle,
  .mobile-menu {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Theme switch (segmented control)
   -------------------------------------------------------------------------- */

.seg {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--scope-bg-1);
  border: var(--scope-hairline) solid var(--scope-line);
  border-radius: var(--scope-radius-sm);
  padding: 2px;
}

.seg--sunken {
  background: var(--scope-bg-0);
}

.seg__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
  box-sizing: border-box;
  border: 0;
  line-height: 1.2;
  background: transparent;
  border-radius: var(--scope-radius-sm);
  color: var(--scope-ink-3);
  font-family: var(--scope-font-mono);
  font-size: var(--scope-text-caption-size);
  padding: var(--scope-pad-seg);
  -webkit-tap-highlight-color: transparent;
}

.seg__btn:hover {
  color: var(--scope-ink-2);
}

.seg__btn[aria-pressed="true"] {
  background: var(--scope-green-tint);
  color: var(--scope-green-hi);
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  border-radius: var(--scope-radius);
  padding: 9px 18px;
  box-sizing: border-box;
}

.btn--primary {
  background: var(--scope-green);
  color: var(--scope-on-accent);
  font-weight: 500;
}

.btn--primary:hover {
  background: var(--scope-green-hi);
  color: var(--scope-on-accent);
}

.btn--outline {
  background: var(--scope-outline-btn-bg);
  border: var(--scope-hairline) solid var(--scope-green);
  color: var(--scope-green);
  font-family: var(--scope-font-mono);
}

.btn--outline:hover {
  border-color: var(--scope-green-hi);
  color: var(--scope-green-hi);
  background: var(--scope-green-tint);
}

/* --------------------------------------------------------------------------
   Cards and panels
   -------------------------------------------------------------------------- */

.card {
  background: var(--scope-bg-1);
  border: var(--scope-hairline) solid var(--scope-line-2);
  border-radius: var(--scope-radius);
  overflow: hidden;
}

/* Chrome strip along the top of a card, mirroring the app's panel headers. */
.card__head {
  height: var(--scope-h-panel-header);
  box-sizing: border-box;
  background: var(--scope-bg-2);
  border-bottom: var(--scope-hairline) solid var(--scope-line);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
}

.card__body {
  padding: 18px;
}

.card__body--roomy {
  padding: 20px 18px;
}

/* Status readout: a filled bullet plus a tracked label. */
.led {
  font-family: var(--scope-font-mono);
  font-size: var(--scope-text-micro-size);
  letter-spacing: var(--scope-text-micro-tracking);
  color: var(--scope-green);
  white-space: nowrap;
}

/* Card that is itself a link (contact tiles). */
.tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--scope-bg-1);
  border: var(--scope-hairline) solid var(--scope-line);
  border-radius: var(--scope-radius);
  padding: 16px 18px;
  transition:
    border-color 0.12s,
    background-color 0.12s;
}

/* Same highlight as the chips: green border and tint, value text in green. */
.tile:hover,
.tile:focus-visible {
  border-color: var(--scope-green);
  background: var(--scope-green-tint);
}

.tile__value {
  font-size: 16px;
  color: var(--scope-ink-1);
  transition: color 0.12s;
}

.tile:hover .tile__value,
.tile:focus-visible .tile__value {
  color: var(--scope-green-hi);
}

.stat {
  background: var(--scope-bg-1);
  border: var(--scope-hairline) solid var(--scope-line);
  border-radius: var(--scope-radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.stat__number {
  font-family: var(--scope-font-mono);
  font-weight: 500;
  font-size: 28px;
  color: var(--scope-ink-1);
}

.stat__label {
  font-family: var(--scope-font-mono);
  font-size: var(--scope-text-micro-size);
  letter-spacing: var(--scope-text-nav-tracking);
  color: var(--scope-ink-3);
}

/* --------------------------------------------------------------------------
   Chips
   -------------------------------------------------------------------------- */

.chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.chip {
  font-family: var(--scope-font-mono);
  font-size: 11px;
  color: var(--scope-ink-2);
  background: var(--scope-bg-1);
  border: var(--scope-hairline) solid var(--scope-line);
  border-radius: var(--scope-radius-sm);
  padding: 4px 8px;
  cursor: default;
  transition:
    color 0.12s,
    border-color 0.12s,
    background-color 0.12s;
}

/* Quieter variant used inside a role entry. */
.chip--ghost {
  font-size: var(--scope-text-micro-size);
  color: var(--scope-ink-3);
  background: transparent;
  padding: 3px 7px;
}

/* Chips are labels, not links, so they keep the default cursor; the hover
   highlight matches the social buttons on queuesee.app. Gated on a real
   hover device so touch screens do not leave a chip stuck lit. */
@media (hover: hover) {
  .chip:hover {
    color: var(--scope-green-hi);
    border-color: var(--scope-green);
    background: var(--scope-green-tint);
  }
}

/* --------------------------------------------------------------------------
   Career timeline

   One shape for every employer: a date column, then the employer, a one-line
   summary and a list of positions. Single-position employers use the same
   list as multi-position ones so the entries read as a set.
   -------------------------------------------------------------------------- */

.roles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.role {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  gap: 14px 28px;
  padding-block: 36px;
  border-top: var(--scope-hairline) solid var(--scope-line);
}

.role:first-child {
  padding-top: 0;
  border-top: 0;
}

.role:last-child {
  padding-bottom: 0;
}

.role__when {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.role__when .meta {
  white-space: nowrap;
}

.role__years {
  font-family: var(--scope-font-mono);
  font-size: 13px;
  color: var(--scope-ink-1);
}

.role__detail {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.role__head {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.role__employer {
  font-size: 22px;
}

.role__summary {
  font-size: 16px;
  line-height: 1.6;
  color: var(--scope-ink-2);
  max-width: 640px;
}

/* Positions held at one employer, as rows in a bordered panel. */
.positions {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  border: var(--scope-hairline) solid var(--scope-line);
  border-radius: var(--scope-radius);
  overflow: hidden;
}

.positions__item {
  display: grid;
  grid-template-columns: 136px minmax(0, 1fr);
  gap: 6px 16px;
  padding: 14px 16px;
  background: var(--scope-bg-1);
  border-bottom: var(--scope-hairline) solid var(--scope-line);
}

.positions__item:last-child {
  border-bottom: 0;
}

.positions__when {
  font-family: var(--scope-font-mono);
  font-size: 11px;
  color: var(--scope-ink-3);
  padding-top: 4px;
  white-space: nowrap;
}

.positions__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.positions__role {
  font-size: 16px;
  color: var(--scope-ink-1);
}

.positions__blurb {
  font-size: 15px;
  line-height: 1.6;
  color: var(--scope-ink-2);
  max-width: 620px;
}

.positions__body .chips {
  margin-top: 2px;
}

/* Below tablet width both columns stack: dates sit above what they date. */
@media (max-width: 599px) {
  .role,
  .positions__item {
    grid-template-columns: minmax(0, 1fr);
  }

  .positions__when {
    padding-top: 0;
  }
}

/* --------------------------------------------------------------------------
   Hero / feature blocks
   -------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(56px, 10vw, 104px) clamp(56px, 9vw, 88px);
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.hero__actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.fact {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.fact__value {
  font-size: 16px;
  line-height: 1.55;
  color: var(--scope-ink-2);
}

.fact__link {
  color: var(--scope-green);
}

.fact__link:hover {
  color: var(--scope-green-hi);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  border-top: var(--scope-hairline) solid var(--scope-line);
  padding-block: 36px 32px;
}

.site-footer__bar {
  display: flex;
  gap: 16px 24px;
  flex-wrap: wrap;
  align-items: center;
}

.site-footer__mark {
  flex: 1 1 auto;
  min-width: 0;
}

/* Location and year travel together, so a narrow screen gets the wordmark
   on one line and both of them on the next, never the year on its own. */
.site-footer__meta {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Accessibility helpers
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--scope-bg-2);
  color: var(--scope-ink-1);
  border: var(--scope-hairline) solid var(--scope-green);
  border-radius: var(--scope-radius-sm);
  padding: 10px 16px;
  font-family: var(--scope-font-mono);
  font-size: 12px;
}

.skip-link:focus {
  left: clamp(16px, 5vw, 24px);
  top: 12px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}
