/* ==========================================================================
   Profile sections: stat band · milestones timeline · org structure
   --------------------------------------------------------------------------
   Brand-agnostic. Nothing here names a brand, a colour or a font. Every
   themable value is read from a --ps-* custom property with a neutral
   fallback, so a host maps its own tokens once (on :root or any ancestor)
   and the sections follow.

     --ps-accent      emphasis colour (key milestones, figures' unit)
     --ps-muted       secondary text
     --ps-connector   timeline rail and org-tree lines (keep >= 3:1)
     --ps-rule        dividers
     --ps-surface     card fill
     --ps-display     display font     --ps-mono   mono font
     --ps-radius      card radius
     --ps-max, --ps-pad   .ps-wrap width: min(--ps-max, 100% - 2 * --ps-pad)
     --ps-unit        text size every font size is a multiple of

   Font sizes are multiples of --ps-unit, never rem: some hosts shrink the
   root (Shopify's Dawn family sets html to 62.5%, so 1rem is 10px there).
   --ps-unit defaults to the section's own inherited text size (1em, taken
   once at the section and passed down as a fixed length), which is 16px on
   a typical desktop page whatever the root is.

   This exact file ships twice: travozet.com (public/assets/css/) and the
   Shopify theme (shopify/assets/). Keep the two copies byte-identical.

   Layout switches are container queries, not viewport media queries, so a
   section behaves correctly wherever it is dropped — full width, in a
   column, or in a sidebar.

   Empty handling. The Shopify sections never output an empty field. The
   static HTML relies on the :has()/:empty rules at the end of this file,
   so clearing a value between its tags removes it from the page.
   ========================================================================== */

.ps-sr-only{
  position:absolute !important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Resolved palette. A host that sets nothing still gets sensible proportions:
   secondary text, dividers, connectors and card fill are derived from the
   section's own text colour. (currentColor inside a custom property resolves
   where the property is used, so these follow each element's colour.) */
/* Registered so 1em resolves to a length once, at the section, and every
   element inside inherits that length rather than its own em. */
@property --_unit{ syntax:'<length>'; inherits:true; initial-value:16px; }
:where(.stat-band, .milestones, .org-tree){
  --_unit:var(--ps-unit, 1em);
  --_accent:var(--ps-accent, currentColor);
  --_muted:var(--ps-muted, color-mix(in srgb, currentColor 72%, transparent));
  --_rule:var(--ps-rule, color-mix(in srgb, currentColor 18%, transparent));
  --_connector:var(--ps-connector, color-mix(in srgb, currentColor 58%, transparent));
  --_surface:var(--ps-surface, color-mix(in srgb, currentColor 5%, transparent));
}

/* Optional wrappers for hosts without their own section/container system. */
.ps-section{ padding-block:var(--ps-space, clamp(56px, 8vw, 120px)); }
.ps-wrap{ width:min(var(--ps-max, 1240px), calc(100% - 2 * var(--ps-pad, clamp(20px, 4vw, 64px)))); margin-inline:auto; }
.ps-head{ margin-bottom:clamp(28px, 4vw, 56px); max-width:62ch; }
.ps-eyebrow{
  margin:0 0 14px; font-family:var(--ps-mono, ui-monospace, monospace);
  font-size:calc(.72 * var(--_unit)); letter-spacing:.14em; text-transform:uppercase; font-weight:600;
  color:var(--_accent);
}
.ps-title{ margin:0; font-family:var(--ps-display, inherit); font-size:clamp(2 * var(--_unit), 4vw, 3.4 * var(--_unit)); line-height:1; letter-spacing:-.03em; font-weight:500; text-wrap:pretty; }
.ps-intro{ margin:18px 0 0; color:var(--_muted); font-size:clamp(1 * var(--_unit), 1.4vw, 1.2 * var(--_unit)); line-height:1.55; }
.ps-intro p{ margin:0 0 .9em; }
.ps-intro p:last-child{ margin-bottom:0; }

.stat-band__list,
.milestones__list,
.org-tree__list{ list-style:none; margin:0; padding:0; }
.stat-band__list p, .milestones__list p, .org-tree__list p{ margin:0; }


/* --------------------------------------------------------------------------
   1. STAT BAND
   -------------------------------------------------------------------------- */
.stat-band__frame{ container:ps-stats / inline-size; }

.stat-band__list{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
}
.stat-band__item{
  min-width:0;
  padding:clamp(18px, 3cqi, 30px) clamp(12px, 2.4cqi, 28px) clamp(18px, 3cqi, 30px) 0;
  border-top:1px solid var(--_rule);
}
.stat-band__value{
  display:flex; flex-wrap:wrap; align-items:baseline; column-gap:.3em;
  font-family:var(--ps-display, inherit);
  line-height:.95; letter-spacing:-.045em;
}
.stat-band__figure{
  font-size:clamp(2 * var(--_unit), 9cqi, 4.4 * var(--_unit)); font-weight:500;
  font-variant-numeric:tabular-nums lining-nums;
  white-space:nowrap;
}
.stat-band__unit{
  font-size:clamp(.95 * var(--_unit), 2.6cqi, 1.45 * var(--_unit)); font-weight:500;
  letter-spacing:-.01em;
  color:var(--_accent);
}
.stat-band__label{
  margin-top:12px; max-width:22ch;
  font-size:calc(.9 * var(--_unit)); line-height:1.4;
  color:var(--_muted);
}

/* Wide: one row, however many figures there are. */
@container ps-stats (min-width: 820px){
  .stat-band__list{ grid-template-columns:none; grid-auto-flow:column; grid-auto-columns:minmax(0, 1fr); }
  .stat-band__item{ padding-left:clamp(16px, 2.2cqi, 32px); border-top:0; border-left:1px solid var(--_rule); }
  .stat-band__item:first-child{ padding-left:0; border-left:0; }
  /* Sized so the longest figure ("185,000" is 3.9em wide) plus its unit fits one
     line of a quarter-column: 4.1cqi is ~51px at a 1240px frame. */
  .stat-band__figure{ font-size:clamp(2.4 * var(--_unit), 4.1cqi, 3.6 * var(--_unit)); }
}
/* Very narrow (a sidebar, or a 320px phone): stack. */
@container ps-stats (max-width: 300px){
  .stat-band__list{ grid-template-columns:1fr; }
}


/* --------------------------------------------------------------------------
   2. MILESTONES TIMELINE
   Vertical by default; horizontal once the frame is wide enough to give each
   point a readable column. The rail is drawn per item, from this point's dot
   to the next point's dot, so it starts and ends exactly on the first and
   last dots whatever the text lengths are.
   -------------------------------------------------------------------------- */
.milestones__frame{
  container:ps-timeline / inline-size;
  --dot:14px;
  --dot-key:24px;
  --rail:2px;
  --axis:12px;            /* dot centre, measured from the item's start edge */
}

.milestones__item{
  position:relative;
  min-width:0;
  padding:0 0 clamp(22px, 3cqi, 34px) calc(var(--axis) * 2 + 16px);
}
/* the dot */
.milestones__item::before{
  content:""; position:absolute; z-index:1;
  left:calc(var(--axis) - var(--dot) / 2);
  top:calc(var(--axis) - var(--dot) / 2);
  width:var(--dot); height:var(--dot); border-radius:50%;
  background:var(--ps-dot-fill, currentColor);
  box-shadow:0 0 0 4px var(--ps-dot-halo, transparent);
}
/* the rail segment from this dot to the next one */
.milestones__item::after{
  content:""; position:absolute;
  left:calc(var(--axis) - var(--rail) / 2);
  top:var(--axis);
  bottom:calc(-1 * var(--axis));
  width:var(--rail);
  background:var(--_connector);
}
.milestones__item:last-child::after{ display:none; }

.milestones__year{
  font-family:var(--ps-mono, ui-monospace, monospace);
  font-size:calc(1.05 * var(--_unit)); font-weight:600; letter-spacing:.02em;
  line-height:calc(var(--axis) * 2);       /* centres the year on the rail */
  font-variant-numeric:tabular-nums;
}
.milestones__company{
  margin-top:6px;
  font-family:var(--ps-mono, ui-monospace, monospace);
  font-size:calc(.68 * var(--_unit)); font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  color:var(--_muted);
}
.milestones__text{
  margin-top:8px;
  font-size:calc(.98 * var(--_unit)); line-height:1.45;
  max-width:46ch;
}

/* The points that matter: a larger ringed dot and a larger accent year.
   Size and weight carry the emphasis as well as colour (WCAG 1.4.1). */
.milestones__item--key::before{
  left:calc(var(--axis) - var(--dot-key) / 2);
  top:calc(var(--axis) - var(--dot-key) / 2);
  width:var(--dot-key); height:var(--dot-key);
  background:var(--_accent);
  box-shadow:0 0 0 5px var(--ps-key-halo, color-mix(in srgb, var(--_accent) 22%, transparent));
}
.milestones__item--key .milestones__year{
  color:var(--_accent);
  font-family:var(--ps-display, inherit);
  font-size:calc(1.9 * var(--_unit)); font-weight:600; letter-spacing:-.03em;
}
.milestones__item--key .milestones__text{ font-weight:600; }

/* Horizontal. Sized for ten points: the switch comes at 1150px, where each
   column is 115px and leaves 105px of text box. That fits the widest word in
   the Travozet copy ("polycarbonate", bold at .9 units = 14.4px, ~101px)
   with room to spare. Below 1150 the timeline stays vertical. */
@container ps-timeline (min-width: 1150px){
  .milestones__list{
    display:grid;
    grid-auto-flow:column;
    grid-auto-columns:minmax(0, 1fr);
  }
  .milestones__item{
    padding:calc(var(--axis) * 2 + 18px) 10px 0 0;
  }
  .milestones__item::after{
    left:var(--axis);
    right:calc(-1 * var(--axis));
    top:calc(var(--axis) - var(--rail) / 2);
    bottom:auto;
    width:auto;
    height:var(--rail);
  }
  .milestones__text{
    max-width:none;
    font-size:calc(.9 * var(--_unit));
    /* last resort for a word an editor makes too long for a column: break it
       rather than let it run into the next point */
    overflow-wrap:break-word;
  }
  .milestones__item--key .milestones__year{ font-size:clamp(1.5 * var(--_unit), 2.2cqi, 2 * var(--_unit)); }
}
/* More than ten points will not fit one row legibly — scroll instead of crush. */
@container ps-timeline (min-width: 1150px){
  .milestones__list:has(> .milestones__item:nth-child(11)){
    grid-auto-columns:minmax(140px, 1fr);
    overflow-x:auto; overscroll-behavior-x:contain;
    scroll-snap-type:x proximity; padding-bottom:12px;
  }
  .milestones__list:has(> .milestones__item:nth-child(11)) > .milestones__item{ scroll-snap-align:start; }
}


/* --------------------------------------------------------------------------
   3. ORG STRUCTURE
   Semantic nested lists: the hierarchy exists for assistive tech even with
   the lines switched off. Narrow: an indented tree with elbow connectors.
   Wide: the second level lays out as an org-chart row; deeper levels stay
   indented inside their column.
   -------------------------------------------------------------------------- */
.org-tree__frame{
  container:ps-org / inline-size;
  --indent:28px;          /* horizontal run of each elbow */
  --gutter:14px;          /* how far the trunk sits in from the parent card */
  --gap:14px;             /* vertical space between sibling cards */
  --elbow:30px;           /* elbow height, from the card's top edge */
  --line:2px;
}

.org-tree__card{
  position:relative;
  display:grid; gap:4px;
  padding:clamp(16px, 2.4cqi, 24px);
  border:1px solid var(--_rule);
  border-radius:var(--ps-radius, 16px);
  background:var(--_surface);
}
.org-tree__logo{ display:flex; align-items:center; height:44px; margin-bottom:12px; }
.org-tree__logo img{ display:block; width:auto; height:auto; max-width:150px; max-height:44px; object-fit:contain; }
.org-tree__name{
  margin:0;
  font-family:var(--ps-display, inherit);
  font-size:calc(1.2 * var(--_unit)); line-height:1.1; letter-spacing:-.02em; font-weight:600;
}
.org-tree__meta{
  font-family:var(--ps-mono, ui-monospace, monospace);
  font-size:calc(.74 * var(--_unit)); font-weight:600; letter-spacing:.08em;
  color:var(--_accent);
}
.org-tree__desc{ margin-top:4px; font-size:calc(.92 * var(--_unit)); line-height:1.45; color:var(--_muted); }

/* Level 0 — the parent. */
.org-tree__node--l0 > .org-tree__card{ max-width:560px; }
.org-tree__node--l0 > .org-tree__card .org-tree__logo{ height:60px; }
.org-tree__node--l0 > .org-tree__card .org-tree__logo img{ max-width:190px; max-height:60px; }
.org-tree__node--l0 > .org-tree__card .org-tree__name{ font-size:clamp(1.4 * var(--_unit), 3cqi, 1.9 * var(--_unit)); }
/* Level 2 — the smallest cards. */
.org-tree__node--l2 > .org-tree__card{ padding:14px 16px; }
.org-tree__node--l2 > .org-tree__card .org-tree__logo{ height:34px; margin-bottom:8px; }
.org-tree__node--l2 > .org-tree__card .org-tree__logo img{ max-width:120px; max-height:34px; }
.org-tree__node--l2 > .org-tree__card .org-tree__name{ font-size:calc(1.02 * var(--_unit)); }

/* ---- indented tree (default, every nested level) ---- */
.org-tree__list--l1,
.org-tree__list--l2{
  margin-left:var(--gutter);
  padding-left:var(--indent);
}
.org-tree__node--l1,
.org-tree__node--l2{
  position:relative;
  padding-top:var(--gap);
}
/* trunk: runs the full height of every sibling except the last */
.org-tree__node--l1::before,
.org-tree__node--l2::before{
  content:""; position:absolute;
  left:calc(-1 * var(--indent));
  top:0; bottom:0;
  border-left:var(--line) solid var(--_connector);
}
/* the last sibling's trunk stops at its elbow: └ rather than ├ */
.org-tree__node--l1:last-child::before,
.org-tree__node--l2:last-child::before{
  bottom:auto;
  height:calc(var(--gap) + var(--elbow));
}
/* elbow */
.org-tree__node--l1::after,
.org-tree__node--l2::after{
  content:""; position:absolute;
  left:calc(-1 * var(--indent));
  top:calc(var(--gap) + var(--elbow) - var(--line) / 2);
  width:calc(var(--indent) - 2px);
  border-top:var(--line) solid var(--_connector);
}

/* ---- org-chart row for the second level, when there is room ---- */
@container ps-org (min-width: 860px){
  .org-tree__node--l0 > .org-tree__card{ margin-inline:auto; }

  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))){
    display:grid;
    grid-auto-flow:column;
    grid-auto-columns:minmax(0, 1fr);
    align-items:start;
    margin:calc(var(--elbow) * 1.2) 0 0;
    padding:0;
  }
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))) > .org-tree__node{
    padding:calc(var(--elbow) * 1.2) 10px 0;
  }
  /* horizontal bar, drawn per column so it runs first-centre to last-centre */
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))) > .org-tree__node::before{
    left:0; right:0; top:0; bottom:auto; height:0;
    border-left:0;
    border-top:var(--line) solid var(--_connector);
  }
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))) > .org-tree__node:first-child::before{ left:50%; }
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))) > .org-tree__node:last-child::before{ right:50%; }
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))) > .org-tree__node:only-child::before{ display:none; }
  /* tick from the bar down to each card */
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))) > .org-tree__node::after{
    left:calc(50% - var(--line) / 2);
    top:0; width:0;
    height:calc(var(--elbow) * 1.2);
    border-top:0;
    border-left:var(--line) solid var(--_connector);
  }
  /* if any card in the row has a logo, reserve the logo height on all of them
     so the names line up; the empty box is whitespace, not a placeholder */
  .org-tree__list--l1:not(:has(> .org-tree__node:nth-child(5))):has(> .org-tree__node > .org-tree__card img[src]:not([src=""]))
    > .org-tree__node > .org-tree__card > .org-tree__logo{ display:flex; }
  /* stem from the parent card down to the bar. Two flat rules because :has()
     cannot nest: draw it whenever there is a second level, then withdraw it
     when that level has fallen back to the indented tree. */
  .org-tree__node--l0:has(> .org-tree__list--l1 > .org-tree__node) > .org-tree__card::after{
    content:""; position:absolute;
    left:calc(50% - var(--line) / 2);
    top:100%;
    height:calc(var(--elbow) * 1.2 + 1px);
    border-left:var(--line) solid var(--_connector);
  }
  .org-tree__node--l0:has(> .org-tree__list--l1 > .org-tree__node:nth-child(5)) > .org-tree__card::after{
    content:none;
  }
}


/* --------------------------------------------------------------------------
   Empty handling for hand-authored HTML.
   Clear a value between its tags and the page drops it:
   an empty figure removes its whole stat, an empty year or text removes the
   milestone, an empty name removes the card and everything nested under it.
   A band, timeline or tree with nothing left in it disappears entirely.
   -------------------------------------------------------------------------- */
.stat-band__unit:empty,
.stat-band__label:empty,
.milestones__company:empty,
.org-tree__meta:empty,
.org-tree__desc:empty,
.org-tree__logo:not(:has(img[src]:not([src=""]))){ display:none; }

.stat-band__item:has(.stat-band__figure:empty),
.milestones__item:has(.milestones__year:empty),
.milestones__item:has(.milestones__text:empty),
.org-tree__node:has(> .org-tree__card .org-tree__name:empty){ display:none; }

/* :has() may not be nested inside :has() — a selector that tries is dropped
   whole — so the section-level rules test the fields directly. */
.stat-band:not(:has(.stat-band__figure:not(:empty))),
.milestones:not(:has(.milestones__year:not(:empty))),
.milestones:not(:has(.milestones__text:not(:empty))),
.org-tree:not(:has(.org-tree__name:not(:empty))){ display:none; }
