/* Production overrides on top of the machine-scoped v3.css.
   Kept in its own file so regenerating v3.css never wipes them. */

/* The ported design ships a dev annotation on every empty image slot
   ("IMG 05 - Beauty of Pets 1920x1200"). On a live site that reads as
   unfinished, so empty slots become plain on-palette panels instead. */
.v3 .img-slot {
  outline: none;
  background: linear-gradient(140deg, #F1F1EC, var(--accent-soft, color-mix(in srgb, var(--ember, #FF5A1F) 14%, #ffffff)));
  transition: background 0.4s ease;
}

.v3 .img-slot::after {
  content: none;
}

/* a real photo dropped into a slot keeps the radius, drops the tint */
.v3 .v3-photo-slot {
  overflow: hidden;
  background: none;
  outline: none;
}

.v3 .v3-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

/* The ported design assumes it owns the whole page. Here it is one band of
   a longer document, so it carries its own paper ground and a top edge to
   separate it from the older scenes above. */
.v3 {
  position: relative;
  display: block;
  background: var(--background-white);
  color: var(--ink);
  --accent: var(--ember, #FF5A1F);
  --accent-soft: var(--benefit-slot-tint, color-mix(in srgb, var(--ember, #FF5A1F) 14%, #ffffff));
  --accent-deep: var(--benefit-deep, color-mix(in srgb, var(--ember, #FF5A1F) 80%, #000000));
}


/* Two-face type system: Clash Display for headings, Red Hat Mono for
   everything else. Overriding --font-body here rather than in v3.css keeps
   the generated file regenerable. */
.v3 {
  --font-body: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
}

/* mono runs a touch large at the same px, and needs more air between lines */
.v3 p,
.v3 li,
.v3 .lead {
  font-size: 0.95em;
  letter-spacing: -0.01em;
}

.v3 .lead {
  line-height: 1.45;
}


/* one published project: the card takes the whole row */
.v3 .work-card--full {
  grid-column: span 6;
}

.v3 .work-card--full .work-card__media .img-slot {
  aspect-ratio: 21 / 9;
}


/* ============================================================
   PROJECT ARCHIVE + SINGLE
   Own namespace (pj__) rather than the older psingle__ classes, which
   still carry the pre-flip dark styling elsewhere in style.css.
   ============================================================ */

/* the whole card is clickable, but the arrow keeps the real focus target */
.v3 .work-card__link {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.v3 .work-card__go { z-index: 2; }

.v3 .pj-pagination {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  display: flex;
  justify-content: center;
}

.v3 .pj-pagination .nav-links {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.v3 .pj-pagination a,
.v3 .pj-pagination span {
  padding: 0.55rem 1rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  font-size: 0.85rem;
}

.v3 .pj-pagination .current {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--white);
}

.v3 .pj-empty { color: var(--ink-muted); }

/* ---- single ---- */

.v3 .pj__back { text-decoration: underline; text-underline-offset: 3px; }

.v3 .pj__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

.v3 .pj__title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 7vw, 5.5rem);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.03em;
  max-width: 18ch;
}

.v3 .pj__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.v3 .pj__media {
  margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
  border-radius: var(--radius-card);
}

.v3 .pj__grid {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) 2.1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

/* the facts card rides along instead of scrolling away */
.v3 .pj__aside {
  position: sticky;
  top: 7rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: flex-start;
}

.v3 .pj__facts {
  width: 100%;
  padding: 1.5rem;
}

.v3 .pj__facts h2 {
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 1rem;
}

.v3 .pj__row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 0;
  border-top: 1px solid var(--hairline);
  font-size: 0.85rem;
}

.v3 .pj__row-label { color: var(--ink-muted); flex: none; }
.v3 .pj__row-value { text-align: right; font-weight: 500; }

.v3 .pj__block + .pj__block { margin-top: clamp(2rem, 4vw, 3rem); }

.v3 .pj__block h2 {
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  margin-bottom: 0.75rem;
}

.v3 .pj__block p { color: var(--ink-muted); max-width: 62ch; }

.v3 .pj__nav {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(3.5rem, 8vw, 6rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--hairline);
}

.v3 .pj__nav-link { display: grid; gap: 0.35rem; }
.v3 .pj__nav-link--next { text-align: right; justify-items: end; }

.v3 .pj__nav-link strong {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2vw, 1.5rem);
  font-weight: 600;
}

.v3 .pj__nav-link:hover strong { color: var(--accent); }

@media (max-width: 860px) {
  .v3 .pj__grid { grid-template-columns: 1fr; }
  .v3 .pj__aside { position: static; }
}

/* The pre-rebuild horizontal works rail in style.css still owns a bare
   .work-card rule (width: 38vw; min-width: 420px; flex-shrink: 0). Same class
   name, so it was forcing every grid card to one oversized width and pushing
   the row out of the container. Grid items also need min-width: 0 before they
   are allowed to shrink under their content. Fixes the legacy .work-card. */
.v3 .work-grid > .work-card {
  width: auto;
  min-width: 0;
  flex-shrink: 1;
}

.v3 .work-grid { min-width: 0; }
/* ---- Header logo, inlined ----
   Same box the <img> occupied. The wordmark takes currentColor so it
   follows .rnav__logo through its existing states: dark down the page,
   white while the nav is over the hero, ember on hover, with the colour
   transition that rule already carries. */
.rnav__logo-svg{
  display: block;
  height: 40px;
  width: auto;
}

.logo-text{
  fill: currentColor;
  transition: fill .5s var(--fp-ease-out);
}

.logo-box-bg{
  fill: var(--ember, #FF5A1F);
  transition: fill .4s var(--fp-ease-out);
}

@media (max-width: 600px){
  .rnav__logo-svg{ height: 30px; }
}

/* ---- Hybrid liquid surface ----
   The canvas is the verdict's ground, so it sits under that panel's
   content and fills it. Square corners are forced: main.js writes a
   50px radius inline on its own canvases, and an inline style only
   loses to !important. The host is absolutely positioned so it never
   becomes a cell of the verdict's grid. */
.hybrid__liquid{
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.hybrid__liquid canvas{
  display: block;
  width: 100% !important;
  height: 100% !important;
  border-radius: 0 !important;
}

.hybrid__verdict > h2,
.hybrid__verdict > .hybrid__art{
  position: relative;
  z-index: 1;
}

/* ---- Hybrid Split Panel 01 (THE DESIGNER) white text ---- */
#panelLight,
.hybrid__panel--light{
  color: #FFFFFF !important;
}

#panelLight .hybrid__tag,
.hybrid__panel--light .hybrid__tag{
  color: #FFFFFF !important;
  opacity: 0.85;
}

#panelLight h2,
#panelLight h2 em,
.hybrid__panel--light .hybrid__content h2,
.hybrid__panel--light .hybrid__content h2 em{
  color: #FFFFFF !important;
}

/* ============================================================
   HYBRID VERDICT - the panel the split wipes open to reveal.

   Was a centred line on near-black. Now it is the accent ground
   with the verdict on the left and the character on the right,
   which is what the two panels part to show.

   The h2 keeps its opacity/scale start state: the GSAP timeline
   fades it up once the panels are most of the way open, so it
   must not be made visible here.
   ============================================================ */
.hybrid__verdict{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  text-align: left;
  background: var(--fp-ember, #FF5A1F);
  padding-inline: max(var(--fp-margin, 8vw), calc((100% - 96rem) / 2));
  overflow: hidden;
}

.hybrid__verdict h2{
  font-family: var(--fp-font-grotesque);
  font-weight: 600;
  font-stretch: normal;
  font-size: clamp(1.4rem, 3.2vw, 2.75rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  text-transform: none;
  color: #FFFFFF;
  margin: 0;
}

/* the second line is the quieter half of the claim, not an accent */
.hybrid__verdict h2 em{
  display: inline-block;
  font-style: normal;
  font-weight: 500;
  text-transform: none;
  color: #FFFFFF;
}

.hybrid__art{
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-width: 0;
}
.hybrid__art img{
  display: block;
  width: 100%;
  height: auto;
  max-height: 78%;
  object-fit: contain;
  object-position: center bottom;
}

@media (max-width: 760px){
  .hybrid__verdict{
    grid-template-columns: minmax(0, 1fr);
    align-content: center;
    text-align: center;
    gap: 1.5rem;
  }
  .hybrid__art img{ max-height: 34vh; }
}

/* ---- where the scrub never runs ----
   The timeline is inside mm.add("(min-width: 769px) and
   (prefers-reduced-motion: no-preference)"). Below that width, and
   for anyone who asks for less motion, nothing animates: the panels
   would sit frozen at half a screen each and the verdict would stay
   at opacity 0, which is an invisible headline. So in those cases
   the split is dropped and the verdict is simply shown. */
@media (max-width: 768px), (prefers-reduced-motion: reduce){
  .hybrid__pin{ height: auto; min-height: 72vh; }
  .hybrid__panel{ display: none; }
  .hybrid__verdict{
    position: relative;
    inset: auto;
    min-height: 72vh;
    padding-block: clamp(2.5rem, 8vh, 4rem);
  }
  .hybrid__verdict h2{
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ============================================================
   FLIP CARDS - responsive.

   The pinned stage lays four cards at 22vw each. With five lines
   of copy on every card that only holds up once there is room for
   four real columns, so the switch to the stacked grid moves from
   840px up to 1024px, and the grid itself drops to one column
   sooner than it used to.

     >= 1025px   four cards, pinned stage
     681-1024    two columns
     <= 680px    one column
   ============================================================ */
@media (max-width: 1024px){
  .flipsvc__stage{ display: none; }
  .flipsvc__mobile{ display: grid; }
}

.flipsvc__mobile{
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
  padding-block: clamp(2.5rem, 8vh, 5rem);
}

/* every card the same height, claim on the floor of each */
.flipsvc__mcard{
  min-height: 21rem;
  height: 100%;
}

@media (max-width: 680px){
  .flipsvc__mobile{ grid-template-columns: minmax(0, 1fr); }
  .flipsvc__mcard{ min-height: 0; }
}

/* the head stacks its button under the title on narrow screens */
@media (max-width: 680px){
  .flipsvc__headwrap{
    flex-direction: column;
    align-items: flex-start;
    gap: 1.25rem;
  }
}

/* ============================================================
   FLIP CARD BACKS - rebuilt.

   What made them read as filler: a grey-on-grey ground, the title
   shouting in caps, two lines of copy dressed as a dotted list,
   and a 44px number parked in the corner with a field of empty
   space above it.

   Now: the index is a quiet mono mark at the top, next to the same
   accent square the section eyebrows use; the name carries the card;
   the line under it is read as a sentence; and the claim sits at the
   foot as the one piece of colour on the card.
   ============================================================ */
.flipcard__back,
.flipsvc__mcard{
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: clamp(1.5rem, 2.2vw, 2.25rem);
  background: #FFFFFF;
  border: 1px solid rgba(17, 17, 20, .08);
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(17, 17, 20, .04), 0 18px 40px -28px rgba(17, 17, 20, .28);
  color: var(--fp-bone, #111114);
}

/* ---- index, top of the card ---- */
.flipcard__num,
.flipsvc__mcard .flipcard__num{
  order: -1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-align: left;
  font-family: "Red Hat Mono", ui-monospace, monospace;
  font-weight: 600;
  font-size: 12px;
  line-height: 1;
  letter-spacing: 1.11px;
  color: var(--fp-ash, #6B6B73);
}
.flipcard__num::before,
.flipsvc__mcard .flipcard__num::before{
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--ember, #FF5A1F);
  flex: none;
}

/* ---- name ---- */
.flipcard__title,
.flipsvc__mcard .flipcard__title{
  margin: 0;
  font-family: var(--fp-font-grotesque, "Inter Tight", system-ui, sans-serif);
  font-weight: 500;
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--fp-bone, #111114);
}

/* ---- the two lines: sentence, then claim ---- */
.flipcard__back ul,
.flipsvc__mcard ul{
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: .6rem;
}

.flipcard__back li,
.flipsvc__mcard li{
  font-family: "Red Hat Mono", ui-monospace, monospace;
  font-size: .8125rem;
  line-height: 1.5;
  letter-spacing: .2px;
  text-transform: none;
  padding: 0;
  border: 0;
  color: var(--fp-ash, #6B6B73);
}

/* the opening line reads as a sentence and sets up the rest */
.flipcard__back li:first-child,
.flipsvc__mcard li:first-child{
  font-size: .875rem;
  color: var(--fp-bone, #111114);
  padding-bottom: .85rem;
  border-bottom: 1px solid rgba(17, 17, 20, .08);
}

/* the middle lines are the list proper, each with a small accent mark */
.flipcard__back li:not(:first-child):not(:last-child),
.flipsvc__mcard li:not(:first-child):not(:last-child){
  display: flex;
  align-items: baseline;
  gap: .6rem;
}
.flipcard__back li:not(:first-child):not(:last-child)::before,
.flipsvc__mcard li:not(:first-child):not(:last-child)::before{
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 1px;
  background: var(--ember, #FF5A1F);
  flex: none;
  transform: translateY(-2px);
}

/* the claim: at the foot, solid, the one piece of colour */
.flipcard__back li:last-child,
.flipsvc__mcard li:last-child{
  margin-top: auto;
  align-self: flex-start;
  padding: .6rem 1rem;
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .04em;
  color: #FFFFFF;
  background: var(--ember, #FF5A1F);
  border: 0;
}

/* a single line is the sentence, never the claim */
.flipcard__back li:only-child,
.flipsvc__mcard li:only-child{
  margin-top: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--fp-ash, #6B6B73);
  font-weight: 400;
}

@media (max-width: 860px){
  .flipsvc__mcard{ gap: .85rem; }
}


/* the Who I build for band is retired; its copy now rides on the
   capability flip cards, which used to repeat the craft services */
#v3-clients{ display: none; }

/* ============================================================
   CRAFT CARDS - rebuilt to the Figma.

   Four cards, each its own ground, text left and the character
   right. Type is straight off the file:

     title  Clash Display Medium  96 / 100, -2.4px
     desc   Red Hat Mono Regular  18 / 24,   0.2px
     tags   Red Hat Mono Regular  12 / 13.5, 1.11px

   The 96px title is the ceiling; it scales down with the card so
   a narrow screen never gets a headline wider than its own box.
   ============================================================ */

/* the 01 / 04 + DESIGN row is not in the design */
.craft__top{ display: none; }

/* the section heading is gone; each card carries its own title */
.craft__head{ display: none; }

/* the card's own layout is set once, at the end of this file */

/* ---- grounds ---- */
.craft__card-in{ transition: background-color 0.4s ease, border-color 0.4s ease; }
.craft__card--ink1 .craft__card-in{ background: color-mix(in srgb, var(--craft-card-ink1, #1fe2ff) 50%, transparent); background: var(--craft-card-ink1-50, color-mix(in srgb, var(--craft-card-ink1, #1fe2ff) 50%, transparent)); color: #111114; }
.craft__card--bone .craft__card-in{ background: var(--craft-card-bone, #451200); color: #FFFFFF; }
.craft__card--ink2 .craft__card-in{ background: var(--craft-card-ink2, #c4ff1f); border: none; color: #111114; }
.craft__card--ember .craft__card-in{ background: var(--fp-ember, #FF5A1F); color: #FFFFFF; }

.craft__card--bone h3,
.craft__card--bone p,
.craft__card--bone li,
.craft__card--ember h3,
.craft__card--ember p,
.craft__card--ember li{ color: inherit; }

.craft__lead{
  display: flex;
  flex-direction: column;
  gap: clamp(.9rem, 2vw, 1.5rem);
}

.craft__title{
  font-family: var(--fp-font-grotesque, "Inter Tight", system-ui, sans-serif);
  font-weight: 500;
  font-stretch: normal;
  font-size: clamp(2.25rem, 6.4vw, 6rem);
  line-height: 1.042;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  margin: 0;
}

.craft__desc{
  font-family: "Red Hat Mono", ui-monospace, monospace;
  font-weight: 400;
  font-size: clamp(.875rem, 1.2vw, 1.125rem);
  line-height: 1.3333;
  letter-spacing: .2px;
  max-width: 40ch;
  opacity: 1;
  margin: 0;
}

.craft__bottom{ display: block; }

.craft__tags{
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: .5rem;
  max-width: 34rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.craft__tags li{
  font-family: "Red Hat Mono", ui-monospace, monospace;
  font-weight: 400;
  font-size: .75rem;
  line-height: 1.125;
  letter-spacing: 1.11px;
  text-transform: uppercase;
  padding: .55rem 1rem;
  border-radius: 999px;
  background: #FFFFFF;
  color: #111114;
  border: 0;
}

/* lime needs the opposite pill or the white disappears into it */
.craft__card--ink2 .craft__tags li{ background: #111114; color: #FFFFFF; }
.craft__card--bone .craft__tags li{ background: #FFFFFF; color: #111114; }

.craft__art{
  display: flex;
  justify-content: center;
  min-width: 0;
}
.craft__art img{ display: block; }

/* the narrow-screen rules live with the layout, at the end of the file */


/* the row tint the About cards use, in one place so the tools list
   and the experience list can never drift apart. Lightened 96% from accent. */
:root{ --about-row: #fff8f6; }

/* ============================================================
   EYEBROWS - one treatment everywhere, straight off the Figma:
   Red Hat Mono SemiBold 14 / 12, 0.48px tracking, with a 10x10
   accent square beside it.

   Three selectors carry eyebrows on this site: .intro .meta-label
   outside the band, .v3 .meta-label inside it, and the Portfolio
   head which uses a .tag instead. All three are listed so none of
   them keeps its own size or spacing.
   ============================================================ */
.meta-label,
.intro .meta-label,
.v3 .meta-label,
.v3 .portfolio__head .tag--accent{
  display: inline-flex;
  align-items: center;
  gap: 7.8px;
  padding: 0;
  background: none;
  border-radius: 0;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: 14px;
  font-weight: 600;
  line-height: 18.85px;
  letter-spacing: 1.56px;
  text-transform: uppercase;
  color: var(--fp-bone, #111114);
}

.meta-label::before,
.intro .meta-label::before,
.v3 .meta-label::before,
.v3 .portfolio__head .tag--accent::before{
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 2px;
  /* --ember is what the accent picker rewrites, so the squares
     follow whichever colour the visitor chooses */
  background: var(--ember, #FF5A1F);
  flex: none;
}

/* the light variant sits on dark grounds and keeps its own colour */
.v3 .meta-label--light{ color: rgba(255, 255, 255, 0.75); }

/* ---- Work card: year up on the dot row, tags in the accent ---- */
.v3 .work-card__topline{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 .25rem .35rem;
}

.v3 .work-card__topline .work-card__year{
  font-size: .85rem;
  font-weight: 500;
  color: var(--ink-muted);
}

/* solid accent, white type, set as labels rather than sentence case */
.v3 .work-card__tags .tag{
  background: var(--ember, var(--accent, #FF5A1F));
  color: #FFFFFF;
  text-transform: uppercase;
  letter-spacing: .06em;
  transition: background-color 0.4s ease;
}

/* ============================================================
   HOMEPAGE COPY - the pieces the new wording introduced.
   Availability badge, hero buttons, the editorial intro body,
   and the two-paragraph contact card.
   ============================================================ */

/* the headline is a sentence now, with script accents, so the
   uppercase transform has to come off or Caveat is set in caps */
.hero--sky .hero__title{ text-transform: none; }
.hero--sky .hero__title .script{
  font-family: var(--fp-font-mono, "Caveat"), cursive;
  font-family: "Caveat", cursive;
  font-style: normal;
  font-weight: 600;
  color: var(--fp-ember, #FF5A1F);
  letter-spacing: 0;
}

.hero--sky .hero__badge{
  display: inline-flex;
  align-items: center;
  gap: .55em;
  margin: 0 0 1.1rem;
  padding: .4rem .85rem;
  border-radius: 999px;
  background: rgba(255,255,255,.82);
  border: 1px solid rgba(17,17,20,.08);
  font-family: var(--fp-font-mono);
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fp-bone, #111114);
}
.hero--sky .hero__dot{
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #3FBF6A;
  flex: none;
}

.hero--sky .hero__actions{
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin-top: 1.6rem;
}

.hero--sky .hero__micro{
  margin: .9rem 0 0;
  font-family: var(--fp-font-mono);
  font-size: .75rem;
  letter-spacing: .04em;
  color: rgba(255,255,255,.82);
}

.hero--sky .hero__tools{
  max-width: 34rem;
  margin: .7rem 0 0;
  font-family: var(--fp-font-mono);
  font-size: .7rem;
  line-height: 1.6;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255,255,255,.84);
}

/* ---- Editorial intro -------------------------------------------------
   The section ships centred (.intro--statement sets text-align:center and
   centres its flex container). This one is an editorial header row
   instead: statement large on the left, meta small on the right, a rule
   under both, then the body. Laid out as a grid on the container, so the
   children fall into place without any extra wrappers in the template. */
#intro.intro--statement{ text-align: left; }

#intro .intro__container{
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: end;
  justify-items: center;
}

#intro .intro__eyebrow{
  grid-column: 1 / -1;
  margin-bottom: clamp(1.75rem, 4vw, 3rem);
}

#intro .intro__statement{
  grid-column: 1;
  text-align: center;
}

/* the soft peach circle behind the intro, retired. The span is in
   front-page.php, which this tool may not write, and it is decorative
   (aria-hidden) so dropping it in CSS removes it entirely. */
.intro__blob{ display: none; }

#intro .intro__meta{
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  text-align: right;
  white-space: nowrap;
  font-size: .7rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fp-ash, #6B6B73);
}

#intro .intro__body{
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-top: clamp(2rem, 5vw, 3.25rem);
  padding-top: clamp(2rem, 5vw, 3.25rem);
  border-top: 1px solid var(--fp-line, #E4E2DB);
}
#intro .intro__body p{
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--fp-ash, #6B6B73);
}

#intro .intro__closing{
  grid-column: 1 / -1;
  max-width: 24ch;
  margin: clamp(2rem, 5vw, 3.25rem) 0 0;
  font-size: clamp(1.35rem, 3vw, 2.25rem);
  line-height: 1.25;
  font-weight: 600;
  color: var(--fp-bone, #111114);
}

@media (max-width: 760px){
  #intro .intro__container{ grid-template-columns: minmax(0, 1fr); }
  #intro .intro__meta{
    grid-column: 1;
    flex-direction: row;
    gap: 1.25rem;
    text-align: left;
    margin-top: 1.25rem;
  }
  #intro .intro__body{ grid-template-columns: minmax(0, 1fr); }
}

/* ---- Contact card ---- */
.v3 .cta__body{
  max-width: 46ch;
  margin: 0 auto .75rem;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: rgba(255,255,255,.9);
}
.v3 .cta__body + .cta__body{ margin-bottom: 1.75rem; }

.v3 .cta__contacts span{ color: rgba(255,255,255,.75); }

@media (max-width: 600px){
  .hero--sky .hero__actions{ width: 100%; }
  .hero--sky .hero__actions .btn{ flex: 1 1 auto; text-align: center; }
}


/* ---- Featured: the client name strip, on the same carousel ---- */
.v3 .logo-splide{ min-width: 0; flex: 1 1 auto; }
.v3 .logo-splide .splide__track{ overflow: hidden; }
.v3 .logo-splide .splide__list{ margin: 0; padding: 0; list-style: none; align-items: center; }
.v3 .logo-splide .splide__slide{ width: auto; list-style: none; }
.v3 .logo-splide .splide__slide > span{ white-space: nowrap; }

/* ============================================================
   TESTIMONIALS - two rows that drift in opposite directions.
   Each row's cards are printed twice, so translating the track
   by exactly half its width restarts on identical cards and the
   loop never shows a seam. Duration scales with the row so both
   rows travel at the same speed whatever they hold.
   ============================================================ */
.v3 .testimonials{ overflow: hidden; }

.v3 .testimonials__title{
  text-align: center;
  max-width: 20ch;
  margin: 0 auto clamp(2.5rem, 5vw, 3.5rem);
  color: var(--ink, #111114);
}

/* front-page-animations.js wraps every h2 and slides it up from behind a
   mask on scroll. This section is inserted into the page by script, so
   that reveal can be left holding the heading half-hidden. Opt this one
   heading out and let it simply be there. */
.v3 .testimonials__title .global-heading-inner{
  transform: none !important;
  opacity: 1 !important;
  visibility: visible !important;
  color: inherit !important;
}

.v3 .testimonials .section-head{ justify-content: center; }

.v3 .tm-row{
  position: relative;
  overflow: hidden;
  margin-inline: calc(-1 * var(--gutter));
  padding-block: .55rem;
  contain: paint;
}

/* Smooth GPU-friendly edge fade overlays without expensive mask-image repaints */
.v3 .tm-row::before,
.v3 .tm-row::after{
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: clamp(2rem, 6vw, 5rem);
  z-index: 5;
  pointer-events: none;
}
.v3 .tm-row::before{
  left: 0;
  background: linear-gradient(to right, var(--bg, #FAFAF7), transparent);
}
.v3 .tm-row::after{
  right: 0;
  background: linear-gradient(to left, var(--bg, #FAFAF7), transparent);
}

.v3 .tm-row .splide__track{
  overflow: hidden;
  contain: paint;
}

.v3 .tm-row .splide__list{
  margin: 0;
  padding: 0;
  list-style: none;
  align-items: stretch;
  will-change: transform;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}

.v3 .tm-row .splide__slide{
  width: auto;
  height: auto;
  display: flex;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}
.v3 .tm-row .splide__slide > .tm-card{ height: 100%; }

/* ---- the card ---- */
.v3 .tm-card{
  flex: 0 0 auto;
  display: flex;
  gap: 1.1rem;
  width: 500px;
  margin: 0;
  padding: 1rem;
  border-radius: var(--radius-card);
  background: var(--white);
  border: 1px solid var(--hairline);
  will-change: transform;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  contain: layout style;
}

.v3 .tm-card__photo{
  flex: 0 0 15rem;
  align-self: stretch;
  border-radius: 14px;
  overflow: hidden;
  background: var(--bg-soft);
}

/* Astra puts a rule and an indent on every blockquote; the quote here is
   already framed by its own card and does not want a second frame. */
.v3 .tm-card__quote{
  border: 0;
  border-left: 0;
  padding: 0;
  margin: 0;
  quotes: none;
  font-style: normal;
  background: none;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--ink);
}
.v3 .tm-card__quote::before,
.v3 .tm-card__quote::after{ content: none; }
.v3 .tm-card__photo img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.v3 .tm-card__body{
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .9rem;
  min-width: 0;
  padding-right: 2rem;
}

.v3 .tm-card__who{
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: .1rem;
}
.v3 .tm-card__name{ font-weight: 600; font-size: .95rem; }
.v3 .tm-card__role{ font-size: .8rem; color: var(--ink-muted); }

.v3 .tm-card__link{
  position: absolute;
  right: 0;
  bottom: 0;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--bg-soft);
  color: var(--ink);
  font-size: .9rem;
  text-decoration: none;
  transition: background .25s var(--ease-out), color .25s var(--ease-out);
}
.v3 .tm-card__link:hover,
.v3 .tm-card__link:focus-visible,
.v3 .tm-card:hover .tm-card__link{ background: var(--ember, var(--accent, #FF5A1F)); color: #fff; }

/* 500px is wider than a phone, so the card gives that up below 600px
   rather than running off the side of the screen */
@media (max-width: 600px){
  .v3 .tm-card{ width: 88vw; padding: .8rem; gap: .8rem; }
  .v3 .tm-card__photo{ flex-basis: 8rem; }
}

@media (prefers-reduced-motion: reduce){
  /* Auto Scroll is switched off in JS under reduced motion;
     the row stays draggable and scrollable by hand. */
  .v3 .tm-row{ overflow-x: auto; }
}

/* ============================================================
   REVIEW FORM - used by [testimonial_form]
   ============================================================ */
.tmform{
  max-width: 34rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  font-family: var(--fp-font-grotesque);
}

/* the honeypot must be reachable by a bot and invisible to a person */
.tmform__hp{
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.tmform__row{ display: flex; flex-direction: column; gap: .4rem; }

.tmform__row label{
  font-family: var(--fp-font-mono);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fp-ash, #6B6B73);
}
.tmform__row label span{ color: var(--fp-ember, #FF5A1F); }

.tmform__row input[type="text"],
.tmform__row input[type="url"],
.tmform__row textarea{
  width: 100%;
  padding: .8rem .9rem;
  font: inherit;
  font-size: .95rem;
  color: var(--fp-bone, #111114);
  background: #fff;
  border: 1px solid var(--fp-line, #E4E2DB);
  border-radius: 12px;
  transition: border-color .25s, box-shadow .25s;
}
.tmform__row textarea{ resize: vertical; min-height: 8rem; }

.tmform__row input:focus,
.tmform__row textarea:focus{
  outline: none;
  border-color: var(--fp-ember, #FF5A1F);
  box-shadow: 0 0 0 3px rgba(255, 90, 31, .15);
}

.tmform__row small{ font-size: .75rem; color: var(--fp-ash, #6B6B73); }

.tmform__submit{
  align-self: flex-start;
  padding: .85rem 1.6rem;
  border: 0;
  border-radius: 999px;
  background: var(--fp-ember, #FF5A1F);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: transform .25s var(--fp-ease-out), box-shadow .25s;
}
.tmform__submit:hover{
  transform: translateY(-1px);
  box-shadow: 0 12px 28px -12px rgba(255, 90, 31, .7);
}
.tmform__submit:focus-visible{ outline: 2px solid var(--fp-bone, #111114); outline-offset: 3px; }

.tmform__note{
  margin: 0;
  font-size: .8rem;
  color: var(--fp-ash, #6B6B73);
}

.tmform__error{
  margin: 0;
  padding: .8rem 1rem;
  border-radius: 12px;
  background: #FFF1EC;
  border: 1px solid rgba(255, 90, 31, .35);
  color: #8A2B00;
  font-size: .9rem;
}

@media (prefers-reduced-motion: reduce){
  .tmform__submit{ transition: none; }
}


/* ============================================================
   ONE COLUMN FOR THE WHOLE PAGE

   The page runs two container systems that never agreed:

     .v3 .container   width: min(100% - 2*gutter, 1440px), centred
     old scenes       padding-inline: 8vw

   At 1920px that puts one edge at 240px and the other at 154px;
   at 1440px the order flips (64px vs 115px). Every section now
   resolves to the same centred 1440px column instead.
   ============================================================ */
:root{
  --site-max: 1440px;
  --site-gutter: clamp(1.25rem, 4vw, 4rem);
}

/* Applied to the inner content boxes, never to .craft or .flipsvc
   themselves: those wrappers carry no horizontal padding at all, and
   their children are a full-bleed sticky stack and a flip-card track
   that are sized against the wrapper's full width. Padding the
   wrapper squeezes those layouts and collapses the cards. */
/* .craft__card-in is no longer in this list: the craft cards are
   full-bleed panels that set their own padding, and this shared
   column was squeezing their content on wide screens. */
.craft__head,
.flipsvc__head,
.flipsvc__mobile{
  padding-inline: max(var(--site-gutter), calc((100% - var(--site-max)) / 2));
}

/* ---- A centred heading needs its eyebrow centred too. With the
   (MN nn) and (C)2026 spans gone, section-head's space-between has
   only the label left to place, and dropped it on the left edge
   under a centred h2. ---- */
.v3 .portfolio__head .section-head,
.v3 .clients__head .section-head{ justify-content: center; }


/* ---- The three scene eyebrows retired. They read "THE CRAFT",
   "CAPABILITIES" and "SELECTED SHOTS" above their headings; the
   headings say it already. ---- */
.craft__head > p.mono,
.flipsvc__head > p.mono,
.flyg__text > p.mono{ display: none; }


/* ============================================================
   WHO I BUILD FOR - the track carries three filler cards that
   were never given a picture:

     <div class="client-card"><div class="img-slot ar-4-5"></div></div>

   They render as empty cream rectangles between the real four.
   The markup is in front-page.php, which Novamira may not write,
   so they are dropped here instead. Every real card carries
   .client-card--glass, which makes the filler easy to name.
   ============================================================ */
.v3 .clients__track .client-card:not(.client-card--glass){ display: none; }


/* ---- Portrait: a real <img>, inserted by custom_js.js because the
   slot in front-page.php is an empty div. The slot carries the 3:4
   frame; the picture covers it. The dashed outline and the "IMG ..."
   caption that mark an unfilled slot go with it. ---- */
#v3-about .about__photo .img-slot{
  aspect-ratio: 3 / 3.4;
  height: auto;
  min-height: 0;
  outline: 0;
}
#v3-about .about__photo .img-slot::after{ content: none; }

#v3-about .about__photo .img-slot img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}


/* ---- About heading: centred ---- */
#v3-about .section-head{ justify-content: center; }

/* ---- Section meta retired sitewide: the (MN(R) nn) counter and the
   (C)2026 stamp beside every section label ---- */
.meta-num,
.meta-copy{ display: none !important; }

#v3-about .about__title{
  text-align: center;
  margin-inline: auto;
}

/* The About row layout itself lives in v3.css, next to the rest of
   the section. What follows is only what this file adds on top. */

/* the tools card is the shorter of the pair, so its carousel takes
   up the slack and both cards keep a common baseline */
.v3 .about__stack > .about-card:nth-child(2){
  display: flex;
  flex-direction: column;
}

/* card headings read as plain labels here, not as tracked caps */
.v3 .about-card h3{
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin-bottom: 1.25rem;
}

/* ---- Tools & Stacks, as a slow vertical carousel ---------- */
.v3 .tools-slider{
  position: relative;
  /* basis 0, not auto: on auto the viewport grows to the full run of
     rows, the card grows with it, and nothing is ever clipped */
  flex: 1 1 0;
  min-height: 13.5rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 25%, #000 75%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 25%, #000 75%, transparent 100%);
}

/* Splide owns the transform now; the list is only its rail. */
.v3 .tools-slider .tools-list{
  grid-template-columns: none;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Splide writes the height inline as calc(0px + <option>); with the
   option at 100% that resolves to the slider box, which the card sizes. */
.v3 .tools-slider .splide__track{ height: 100% !important; }

/* each row is a fixed-height pill; Splide is told the same number, so
   the rail steps in whole rows and nothing lands half-clipped */
.v3 .tools-slider .tools-list > li{
  display: flex;
  align-items: center;
  list-style: none;
  box-sizing: border-box;
  min-height: 0;
}

.v3 .tools-slider .tools-list li,
.v3 .tools-list li{
  gap: .8rem;
  padding: .7rem .8rem;
  border-radius: 14px;
  background: var(--about-row, #fff8f6) !important;
  transition: background 0.3s ease;
}
.v3 .tools-slider .tools-list li:hover,
.v3 .tools-list li:hover{ background: var(--about-row, #fff8f6) !important; }

/* the logo tiles are the real marks now, so the tile is a plain light
   square and the artwork inside carries the colour */
.v3 .tools-slider .tool-ico--img{
  background: var(--white);
  border: 1px solid var(--hairline);
  padding: 6px;
}
.v3 .tools-slider .tool-ico--img img{
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.v3 .tools-slider .tool-ico{
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--ico-bg, var(--bg-soft));
  color: var(--ico-fg, var(--ink));
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .78rem;
  line-height: 1;
  display: grid;
  place-items: center;
  flex: none;
}

.v3 .tools-slider .tool-body{
  display: flex;
  flex-direction: column;
  gap: .1rem;
  min-width: 0;
}
.v3 .tools-slider .tool-body b{ font-weight: 600; font-size: .95rem; }
.v3 .tools-slider .tool-body small{
  color: var(--ink-muted);
  font-size: .8rem;
  line-height: 1.35;
}

/* ---- Experience, as stacked rows with a date pill --------- */
.v3 .xp-list{
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
.v3 .xp-list li{
  align-items: center;
  padding: 1rem 1.1rem;
  border-bottom: 0;
  border-radius: 16px;
  background: var(--about-row, #fff8f6) !important;
  transition: background 0.3s ease;
}
.v3 .xp-list li:hover{ background: var(--about-row, #fff8f6) !important; }
.v3 .xp-list b{ font-size: 1rem; }
.v3 .xp-list time{
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: .35rem .75rem;
}

@media (max-width: 1024px){
  .v3 .about__stack > .about-card:nth-child(2),
  .v3 .about__stack > .about-card:nth-child(3){
    flex-basis: calc(50% - var(--about-gap) / 2);
  }
}

@media (max-width: 860px){
  .v3 .about__photo,
  .v3 .about__stack > .about-card{ flex-basis: 100%; }
}

@media (prefers-reduced-motion: reduce){
  .v3 .tools-slider .tools-list{ animation: none; }
}


/* ============================================================
   FOOTER - retired. The markup is still in footer.php (PHP is
   outside what Novamira may write), so it is hidden here and
   removed from the DOM in custom_js.js. Sitewide, not just home.
   ============================================================ */
.mnfooter{ display: none !important; }


/* ============================================================
   TINT DOCK - floating accent picker, front page bottom right.
   Supersedes the inline .color-control swatches, which lived in
   .hero__inner and were carried off by its GSAP scroll transform.
   ============================================================ */
.tint-dock{
  position: fixed;
  right: clamp(1rem, 3vw, 2.25rem);
  bottom: clamp(1rem, 3vw, 2.25rem);
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 0;
  padding: .3rem;
  border-radius: 6px;
  background: var(--fp-ink, #FAFAF7);
  border: 1px solid var(--fp-line, #E4E2DB);
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 12px 32px -12px rgba(17,17,20,.28);
  transition: box-shadow .45s var(--fp-ease-out, cubic-bezier(.16,1,.3,1));
}
.tint-dock:hover,
.tint-dock:focus-within{
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 18px 44px -14px rgba(17,17,20,.34);
}

.tint-dock__swatches{ display: flex; align-items: center; gap: 0; }

.tint-dock__chip{
  --size: 20px;
  flex: none;
  width: var(--size);
  height: var(--size);
  padding: 0;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  box-shadow:
    inset 0 0 0 1px rgba(17,17,20,.12),
    0 2px 5px rgba(17,17,20,.18);
  transition:
    width .5s var(--fp-ease-out, cubic-bezier(.16,1,.3,1)),
    margin .5s var(--fp-ease-out, cubic-bezier(.16,1,.3,1)),
    opacity .35s var(--fp-ease-out, cubic-bezier(.16,1,.3,1)),
    transform .3s var(--fp-ease-out, cubic-bezier(.16,1,.3,1)),
    box-shadow .3s var(--fp-ease-out, cubic-bezier(.16,1,.3,1));
}

/* the theme paints button:hover, so the swatch has to hold its own
   fill in every state - base, hover, focus and active alike */
.tint-dock__chip,
.tint-dock__chip:hover,
.tint-dock__chip:focus,
.tint-dock__chip:active{
  background:
    linear-gradient(to bottom, rgba(255,255,255,.45), rgba(255,255,255,0) 42%),
    linear-gradient(to top, rgba(255,255,255,.38), rgba(255,255,255,0) 30%),
    radial-gradient(closest-side circle at 50% 50%, var(--sw) 0%, var(--sw-edge, var(--sw)) 100%)
    !important;
  border: 0 !important;
}

/* collapsed - only the chosen colour is on show */
.tint-dock__chip:not(.is-active){
  width: 0;
  margin-left: 0;
  opacity: 0;
  pointer-events: none;
}
.tint-dock.is-open .tint-dock__chip,
.tint-dock:focus-within .tint-dock__chip{
  width: var(--size);
  margin-left: .5rem;
  opacity: 1;
  pointer-events: auto;
}
/* the row starts flush against the dock's own padding */
.tint-dock.is-open .tint-dock__chip:first-child,
.tint-dock:focus-within .tint-dock__chip:first-child{ margin-left: 0; }

@media (hover: hover){
  .tint-dock:hover .tint-dock__chip{
    width: var(--size);
    margin-left: .5rem;
    opacity: 1;
    pointer-events: auto;
  }
  .tint-dock:hover .tint-dock__chip:first-child{ margin-left: 0; }
  .tint-dock__chip:hover{ transform: scale(1.12); }
}

.tint-dock__chip:focus-visible{
  outline: 2px solid var(--fp-bone, #111114);
  outline-offset: 4px;
}

@media (max-width: 480px){
  .tint-dock__chip{ --size: 18px; }
}

@media (prefers-reduced-motion: reduce){
  .tint-dock,
  .tint-dock__chip{ transition: none; }
}

/* ============================================================
   WEIGHT DOCK - the headline-weight slider, docked bottom left
   opposite the tint dock. Lifted clear of .hero__inner, whose
   GSAP scroll transform faded it out along with the hero.
   ============================================================ */
.weight-dock{
  position: fixed;
  left: clamp(1rem, 3vw, 2.25rem);
  bottom: clamp(1rem, 3vw, 2.25rem);
  z-index: 90;
  display: block;
  width: 12rem;
}

.weight-dock .custom-slider-wrapper{
  width: 100%;
  max-width: none;
  height: 31.6px !important;
  margin: 0 !important;
  padding: 0 !important;
  background-color: var(--fp-ember, #FF5A1F) !important;
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 12px 32px -12px rgba(17,17,20,.28);
  transition:
    background-color .4s var(--fp-ease-out, cubic-bezier(.16,1,.3,1)),
    box-shadow .45s var(--fp-ease-out, cubic-bezier(.16,1,.3,1));
}
.weight-dock .custom-slider-wrapper:hover,
.weight-dock .custom-slider-wrapper:focus-within{
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 18px 44px -14px rgba(17,17,20,.34);
}

.weight-dock .custom-slider-dots span{
  background-color: rgba(255,255,255,.55) !important;
}

/* white marker on the accent ground, as in the hero */
.weight-dock .custom-lab__range::-webkit-slider-thumb{
  background-color: #FFFFFF !important;
  border-radius: 5px !important;
}
.weight-dock .custom-lab__range::-moz-range-thumb{
  background-color: #FFFFFF !important;
  border-radius: 5px !important;
}
.weight-dock .custom-lab__range:focus-visible{
  outline: 2px solid #FFFFFF;
  outline-offset: 4px;
  border-radius: 0;
}

/* below this the tint dock, once open, would run into the slider,
   so the slider takes its own row above it */
@media (max-width: 640px){
  .weight-dock{
    width: 11rem;
    bottom: calc(clamp(1rem, 3vw, 2.25rem) + 3.5rem);
  }
}

@media (prefers-reduced-motion: reduce){
  .weight-dock .custom-slider-wrapper{ transition: none; }
}




/* ============================================================
   SCROLL TO TOP - Astra's own control, brought onto the dock system.
   Astra parks it bottom right on --ast-global-color-0, which is a colour
   the palette does not contain and a corner the tint dock already owns.
   Restyled to match the two docks and lifted clear above the tint dock.
   display is deliberately untouched: Astra's script toggles it.
   ============================================================ */
#ast-scroll-top.ast-scroll-top-icon{
  right: clamp(1rem, 3vw, 2.25rem);
  /* tint dock is ~1.85rem tall, plus a 0.75rem gap */
  bottom: calc(clamp(1rem, 3vw, 2.25rem) + 2.6rem);
  z-index: 90;
  width: 31.6px;
  height: 31.6px;
  /* Astra centres the glyph with line-height, not flex, and its script
     writes display inline - so match its mechanism instead of fighting it.
     line-height therefore has to track the height, or the arrow rides low. */
  line-height: 31.6px;
  padding: 0;
  border: 1px solid var(--fp-line, #E4E2DB);
  border-radius: 6px;
  background-color: var(--fp-ink, #FAFAF7);
  color: var(--fp-bone, #111114);
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 12px 32px -12px rgba(17,17,20,.28);
  transition:
    color .3s var(--fp-ease-out, cubic-bezier(.16,1,.3,1)),
    box-shadow .45s var(--fp-ease-out, cubic-bezier(.16,1,.3,1));
}

/* the shipped arrow carries no fill of its own, so it has to inherit */
#ast-scroll-top.ast-scroll-top-icon .ast-arrow-svg,
#ast-scroll-top.ast-scroll-top-icon .ast-arrow-svg path{
  fill: currentColor;
}

#ast-scroll-top.ast-scroll-top-icon:hover{
  color: var(--fp-ember, #FF5A1F);
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 18px 44px -14px rgba(17,17,20,.34);
}

/* Astra swaps the border to dotted on :focus; give it a real ring instead */
#ast-scroll-top.ast-scroll-top-icon:focus{
  border-style: solid;
  border-color: var(--fp-line, #E4E2DB);
}
#ast-scroll-top.ast-scroll-top-icon:focus-visible{
  outline: 2px solid var(--fp-bone, #111114);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce){
  #ast-scroll-top.ast-scroll-top-icon{ transition: none; }
}

/* ---- tags --------------------------------------------------------
   Squared off to sit with the docks and the chips rather than the pill
   buttons. The accent fill reads --ember (not --accent) on purpose: that
   is the property the tint dock rewrites, so the tags recolour with it. */

.v3 .tag{
  border-radius: 4px;
  line-height: 1;
}

.v3 .tag--accent{
  background: var(--ember);
  color: #fff;
}


/* ---- media sizing -------------------------------------------------
   The fixed 16:10 box is off: card media now takes its height from the
   image itself.

   The :not() guard is the catch. .shots__card and .pj__media only ever
   had height because of this ratio, so a slot with no image inside it
   collapses to nothing once the ratio goes. Those keep it. */

.v3 .ar-16-10{
  aspect-ratio: auto;
}

.v3 .ar-16-10:not(.v3-photo-slot){
  aspect-ratio: 16 / 10;
}

.v3 .work-card__media .img-slot{
  height: 100%;
  width: 100%;
}

/* ---- custom colour well + picker ----------------------------------
   The last chip is not a colour, it is a door. It carries a wheel instead
   of a fill and opens the panel above the dock. */

.tint-dock__chip--custom,
.tint-dock__chip--custom:hover,
.tint-dock__chip--custom:focus,
.tint-dock__chip--custom:active{
  background:
    linear-gradient(to bottom, rgba(255,255,255,.40), rgba(255,255,255,0) 42%),
    conic-gradient(from 90deg,
      #FC5B34, #F09E38, #55BA82, #4CC5D1,
      #4C86F0, #8554F6, #E34798, #E74241, #FC5B34)
    !important;
}

.tint-picker{
  position: absolute;
  right: 0;
  bottom: calc(100% + .5rem);
  width: 12.5rem;
  padding: .6rem;
  display: grid;
  gap: .8rem;
  border-radius: 10px;
  background: var(--fp-ink, #FAFAF7);
  border: 1px solid var(--fp-line, #E4E2DB);
  box-shadow: 0 1px 2px rgba(17,17,20,.05), 0 18px 44px -14px rgba(17,17,20,.34);
}

/* display:grid above would otherwise beat the hidden attribute */
.tint-picker[hidden]{ display: none; }

/* x is saturation, y is value, and the bed under both is the live hue */
.tint-picker__sv{
  position: relative;
  height: 6.5rem;
  border-radius: 6px;
  cursor: crosshair;
  touch-action: none;
  background:
    linear-gradient(to top, #000, rgba(0,0,0,0)),
    linear-gradient(to right, #fff, rgba(255,255,255,0)),
    hsl(var(--tp-hue, 14) 100% 50%);
}

.tint-picker__hue{
  position: relative;
  height: .75rem;
  border-radius: 999px;
  cursor: ew-resize;
  touch-action: none;
  background: linear-gradient(to right,
    #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}

.tint-picker__sv-handle,
.tint-picker__hue-handle{
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(17,17,20,.28);
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.tint-picker__hue-handle{ top: 50%; }

.tint-picker__foot{
  display: flex;
  align-items: center;
  gap: .5rem;
}

.tint-picker__preview{
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(17,17,20,.12);
}

input.tint-picker__hex{
  flex: 1;
  min-width: 0;
  box-sizing: border-box;
  height: 26px;
  padding: 5px 8px;
  border: 0;
  border-radius: 6px;
  background: #f4f4f4;
  color: var(--fp-bone, #111114);
  font-family: var(--fp-font-mono, "Red Hat Mono", monospace);
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0;
}
input.tint-picker__hex:focus-visible{
  outline: 2px solid var(--fp-bone, #111114);
  outline-offset: 2px;
}

/* ============================================================
   MY STACK - flip cards, driven by the stack_item CPT.
   Outer frame is the tinted well, inner faces are the white card, the
   same two-layer build the docks use. Only cards that actually carry a
   description get .is-flippable; the rest are plain logo tiles, so an
   unfilled entry never flips to an empty back.
   ============================================================ */

.v3 .stack__title{
  max-width: 18ch;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.v3 .stack__grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(.75rem, 2vw, 1.5rem);
}

.v3 .stack-card{
  /* the 3D has to be set up on the parent, not the rotating element */
  perspective: 1200px;
  aspect-ratio: 1 / 1;
  padding: 10px;
  border-radius: 28px;
  background: var(--bg-soft);
}

.v3 .stack-card__inner{
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform .65s var(--ease-out);
}

.v3 .stack-card__face{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  padding: 1.5rem;
  border-radius: 20px;
  border: 1px solid var(--hairline);
  background: var(--white);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.v3 .stack-card__face--back{
  transform: rotateX(180deg);
  justify-content: center;
  font-size: .9rem;
  line-height: 1.6;
  color: var(--ink-muted);
  text-align: center;
  overflow: auto;
}

.v3 .stack-card.is-flippable:hover .stack-card__inner,
.v3 .stack-card.is-flippable:focus-visible .stack-card__inner,
.v3 .stack-card.is-flipped .stack-card__inner{
  transform: rotateX(180deg);
}

.v3 .stack-card.is-flippable{ cursor: pointer; }
.v3 .stack-card:focus{ outline: none; }
.v3 .stack-card:focus-visible{
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* ---- front face ---- */

.v3 .stack-card__logo{
  display: grid;
  place-items: center;
  width: clamp(44px, 6vw, 64px);
  height: clamp(44px, 6vw, 64px);
}

.v3 .stack-card__logo img{
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* stand-in until a logo is uploaded */
.v3 .stack-card__initials{
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  border-radius: 14px;
  background: var(--bg-soft);
  color: var(--ink-muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: .02em;
}

.v3 .stack-card__name{
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  text-align: center;
}

@media (max-width: 860px){
  .v3 .stack__grid{ grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 520px){
  .v3 .stack-card{ border-radius: 20px; padding: 8px; }
  .v3 .stack-card__face{ border-radius: 14px; gap: .9rem; }
}

/* a half-second barrel roll is exactly what this setting asks us to drop */
@media (prefers-reduced-motion: reduce){
  .v3 .stack-card__inner{ transition: none; }
}
/* ---- Testimonials section label and real-entry fallback marks ---- */
.v3 .testimonials__eyebrow{
  margin: 0 auto .65rem;
  text-align: center;
  font-family: var(--font-body);
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink);
}

.v3 .tm-card__quote p{
  margin: 0;
}

.v3 .tm-card__quote p + p{
  margin-top: .65rem;
}

.v3 .tm-card__mark{
  display: grid;
  place-items: center;
  background:
    linear-gradient(135deg, rgba(255,90,31,.16), rgba(255,236,228,.72)),
    var(--bg-soft);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 6vw, 5rem);
  font-weight: 600;
  line-height: 1;
}

@media (max-width: 600px){
  .v3 .testimonials__title{ max-width: 12ch; }
  .v3 .tm-card__mark{ font-size: 2.75rem; }
}
.v3 .tm-row--static .splide__list{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.25rem;
}
/* ============================================================
   LIGHT SECTION HEADING READABILITY
   GSAP wraps H1/H2 text in .global-heading-inner for reveal motion.
   Some inherited white heading color was making light-section titles
   disappear on the paper ground, so these sections explicitly return
   to the Meadow Sky ink token while keeping the script accent orange.
   ============================================================ */
.v3 :is(.portfolio, #v3-about, #v3-services, #v3-clients, #v3-benefits, #v3-faq, .testimonials) h2,
.v3 :is(.portfolio, #v3-about, #v3-services, #v3-clients, #v3-benefits, #v3-faq, .testimonials) h2 .global-heading-inner{
  color: var(--ink, #111114) !important;
}

.v3 :is(.portfolio, #v3-about, #v3-services, #v3-clients, #v3-benefits, #v3-faq, .testimonials) h2 .script{
  color: var(--accent, #FF5A1F) !important;
}
/* ============================================================
   FAQ CTA POLISH
   Compact card, clear button, and stable accordion panels on the
   split FAQ layout.
   ============================================================ */
.v3 #v3-faq .faq__cta{
  display: grid;
  gap: 1.1rem;
  align-content: start;
  max-width: 25rem;
  padding: clamp(1.35rem, 3vw, 2rem);
  border-radius: 22px;
  background: var(--white);
  border-color: var(--hairline);
  box-shadow: 0 2px 6px rgba(17,17,20,.04), 0 18px 42px -24px rgba(17,17,20,.28);
}

.v3 #v3-faq .faq__cta b{
  display: block;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  line-height: 1.25;
}

.v3 #v3-faq .faq__cta .btn{
  justify-self: start;
  min-height: 3.45rem;
  padding: .85rem .7rem .85rem 1.35rem;
  gap: .85rem;
  color: var(--white);
  white-space: nowrap;
}

.v3 #v3-faq .faq__cta .btn__arrow{
  width: 2.15rem;
  height: 2.15rem;
  color: var(--accent);
}

.v3 #v3-faq .accordion__panel{
  will-change: max-height;
}

.v3 #v3-faq .accordion__item.is-open .accordion__panel{
  max-height: none;
}

@media (max-width: 640px){
  .v3 #v3-faq .faq__cta{
    max-width: none;
  }
  .v3 #v3-faq .faq__cta .btn{
    width: 100%;
    justify-content: space-between;
  }
}
/* ============================================================
   ABOUT HEADING NORMAL TEXT
   User asked to remove the script/emphasis styling here. Keep the
   heading as one clean Clash Display line with normal word spacing.
   ============================================================ */
.v3 #v3-about .about__title,
.v3 #v3-about .about__title .global-heading-inner{
  color: var(--ink, #111114) !important;
  word-spacing: normal;
}

.v3 #v3-about .about__title .script{
  font-family: inherit !important;
  font-style: normal !important;
  font-weight: inherit !important;
  color: inherit !important;
  margin: 0 !important;
}

/* ---- Selected shots: fixed action button ---- */
.flyg__text .fp-btn{
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: .65rem;
  min-width: 8.6rem;
  min-height: 3rem;
  padding: .84rem 1rem .84rem 1.25rem !important;
  border-radius: 999px;
  border: 1px solid rgba(17,17,20,.22) !important;
  background: #fff !important;
  color: var(--ink, #111114) !important;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .78rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none !important;
  box-shadow: 0 2px 8px rgba(17,17,20,.05), 0 18px 42px -26px rgba(17,17,20,.35);
}
.flyg__text .fp-btn span{
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--accent, #ff5a1f);
  color: #fff;
  font-size: .9rem;
  line-height: 1;
  transform: none !important;
}
.flyg__text .fp-btn:hover{
  border-color: var(--accent, #ff5a1f) !important;
  transform: translateY(-2px);
}
.flyg__text .fp-btn:focus-visible{
  outline: 2px solid var(--ink, #111114);
  outline-offset: 4px;
}

/* ---- Testimonials: sample/dummy image cards ---- */
.v3 .tm-card__photo--dummy img{
  filter: none;
}
.v3 .tm-card__role{
  text-transform: none;
}

@media (max-width: 680px){
  .flyg__text .fp-btn{
    min-width: 8rem;
    min-height: 2.8rem;
    font-size: .72rem;
  }
}

/* ============================================================
   SKY FOOTER CTA - full width animated sky footer
   ============================================================ */
.v3 .site-footer-sky{
  --token-0e44b702-23c6-417a-85ef-a5529e13ec13: #46aeff;
  min-height: min(88svh, 860px);
  margin: 0 !important;
  border-radius: 0 !important;
  padding-block: clamp(4.75rem, 10vw, 8rem) 0 !important;
  background: linear-gradient(180deg, rgb(157, 207, 245) 0%, var(--token-0e44b702-23c6-417a-85ef-a5529e13ec13, rgb(70, 174, 255)) 100%) !important;
  isolation: isolate;
}
.v3 .site-footer-sky::after{
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 42%;
  z-index: 1;
  background: linear-gradient(180deg, rgba(70,174,255,0) 0%, rgba(70,174,255,.22) 62%, rgba(70,174,255,.32) 100%);
  pointer-events: none;
}
.v3 .site-footer-sky > *:not(.sky-canvas){
  position: relative;
  z-index: 2;
}
.v3 .site-footer-sky .sky-canvas{
  opacity: .72;
  mix-blend-mode: screen;
}
.v3 .footer-sky__inner{
  min-height: clamp(32rem, 58vw, 40rem);
  justify-content: flex-start;
  gap: 1rem;
  color: #fff;
}
.v3 .footer-sky__eyebrow{
  margin: 0 0 .15rem;
  font-size: .95rem;
  line-height: 1;
  font-weight: 700;
  color: rgba(255,255,255,.95);
  text-shadow: 0 1px 12px rgba(20,91,145,.18);
}
.v3 .footer-sky__title{
  max-width: 12ch;
  margin: 0 auto;
  font-size: clamp(2.9rem, 5.2vw, 5.7rem);
  line-height: .98;
  font-weight: 650;
  letter-spacing: 0;
  text-shadow: 0 2px 24px rgba(23,96,154,.24);
}
.v3 .footer-sky__title .script{
  margin-inline: .04em;
  color: #fff;
}
.v3 .footer-sky__copy{
  max-width: 44rem;
  margin: .3rem auto .7rem;
  font-size: clamp(.98rem, 1.15vw, 1.1rem);
  line-height: 1.45;
  font-weight: 650;
  color: rgba(255,255,255,.9);
  text-wrap: balance;
  text-shadow: 0 1px 14px rgba(20,91,145,.2);
}
.v3 .footer-sky__button{
  min-height: 3rem;
  padding: .62rem .6rem .62rem 1.1rem;
  font-weight: 700;
  box-shadow: 0 16px 42px -24px rgba(10,65,112,.55);
}
.v3 .footer-sky__button .btn__arrow{
  background: var(--token-0e44b702-23c6-417a-85ef-a5529e13ec13, #46aeff);
  color: #fff;
}
.v3 .footer-sky__contacts{
  width: min(100%, 58rem);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 4vw, 5rem);
  margin: clamp(2.75rem, 6vw, 5rem) auto 0;
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid rgba(255,255,255,.24);
}
.v3 .footer-sky__contact{
  display: grid;
  gap: .65rem;
  justify-items: center;
  text-align: center;
  color: rgba(255,255,255,.92);
}
.v3 .footer-sky__contact span{
  font-size: .95rem;
  font-weight: 750;
  color: #fff;
}
.v3 .footer-sky__contact a,
.v3 .footer-sky__contact p{
  margin: 0;
  font-size: .98rem;
  font-weight: 650;
  color: rgba(255,255,255,.86);
}
.v3 .footer-sky__contact a:hover{
  color: #fff;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.v3 .footer-sky__links{
  display: inline-flex;
  align-items: center;
  gap: .7rem;
}
.v3 .footer-sky__links a{
  min-width: 2.75rem;
  padding: .45rem .75rem;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.32);
  background: rgba(255,255,255,.13);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  line-height: 1;
}
.v3 .site-footer-sky .cta__ghost{
  z-index: 2;
  width: 100%;
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
  font-size: clamp(4.8rem, 15vw, 18rem);
  line-height: .72;
  letter-spacing: 0;
  color: rgba(255,255,255,.22);
  transform: translateY(.08em);
}
.v3 .site-footer-sky .cta__cloud{
  opacity: .62;
  filter: blur(28px);
}
.v3 .site-footer-sky .cta__cloud--1{ width: 420px; height: 130px; top: 29%; left: 27%; }
.v3 .site-footer-sky .cta__cloud--2{ width: 360px; height: 115px; top: 63%; right: 21%; }
.v3 .site-footer-sky .cta__cloud--3{ width: 260px; height: 86px; top: 18%; right: 8%; }

@media (max-width: 760px){
  .v3 .site-footer-sky{
    min-height: 78svh;
    padding-block-start: 4.25rem !important;
  }
  .v3 .footer-sky__inner{
    min-height: 34rem;
  }
  .v3 .footer-sky__contacts{
    grid-template-columns: 1fr;
    gap: 1.3rem;
    width: min(100%, 24rem);
    margin-top: 2.5rem;
  }
  .v3 .site-footer-sky .cta__ghost{
    font-size: clamp(4.2rem, 22vw, 8rem);
  }
}
/* ============================================================
   CRAFT CARDS - final layout, kept at the end of the file so
   nothing later can take the padding back off it.

   The sticky mechanic still wants a 100vh track per card, but
   the visible panel is the Figma's shape: a wide, capped block
   centred in that track, text on the left, character right and
   running the full height of the panel.
   ============================================================ */
.craft__card{
  align-items: center;
  padding: clamp(.5rem, 1.5vw, 1.25rem);
  /* the sticky track stays transparent, so the page ground shows in
     the margin around each coloured panel */
  background: transparent;
}

.craft__card-in{
  display: grid;
  grid-template-columns: minmax(0, 46%) minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 3.5rem);
  align-items: center;

  /* The panel is as tall as its contents, not a fixed block. A fixed
     height left the text column spreading title, blurb and tags across
     far more room than they need, which is the gap in the middle. The
     art below carries its own cap, so that is what sets the height. */
  width: 100%;
  max-width: 96rem;
  height: auto;
  min-height: min(52vh, 26rem);
  max-height: min(88vh, 46rem);
  margin-inline: auto;

  /* equal on all four sides */
  padding: 3rem;
  border-radius: clamp(18px, 2.5vw, 28px);
  overflow: hidden;
}

/* Text column: title, blurb, then the tags after one deliberate gap.
   space-between needed a fixed height to work against; with the panel
   sized to its content the stack just flows and the spacing is even. */
.craft__col{
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(1.25rem, 3vh, 2rem);
  height: 100%;
  max-height: none;
  min-width: 0;
}

.craft__col > .craft__bottom{
  margin-top: clamp(1.5rem, 5vh, 3.25rem);
}

.craft__title{
  font-size: clamp(2.25rem, 4.6vw, 6rem);
  text-wrap: balance;
}

.craft__desc{ max-width: 46ch; }

.craft__tags{ max-width: none; }

/* The character carries its own cap, and that cap is what the panel
   height follows now. */
.craft__art{
  align-items: center;
  height: auto;
  max-height: none;
}
.craft__art img{
  width: 100%;
  height: auto;
  max-height: min(72vh, 38rem);
  object-fit: contain;
  object-position: center bottom;
}

@media (max-width: 1100px){
  .craft__card-in{ grid-template-columns: minmax(0, 52%) minmax(0, 1fr); }
}

/* ---- narrow screens: one column, character in the middle ----
   The markup puts the tags inside .craft__col, above the picture in
   source order. display:contents dissolves that wrapper so .craft__lead,
   .craft__art and .craft__bottom all become rows of the card grid and
   can be ordered title, blurb, character, tags. */
@media (max-width: 860px){
  .craft__card-in{
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: min-content;
    align-content: start;
    gap: clamp(1.25rem, 3.5vh, 2rem);
    height: auto;
    min-height: 0;
    max-height: none;
    padding: clamp(1.25rem, 5vw, 2rem);
  }

  .craft__col{ display: contents; }

  .craft__lead{ order: 1; }
  .craft__art{ order: 2; display: flex; margin-block: clamp(.5rem, 2vh, 1.25rem); }
  .craft__bottom{ order: 3; margin-top: 0; }

  .craft__art img{
    max-height: 46vh;
    object-position: center center;
  }

  .craft__title{ font-size: clamp(1.9rem, 8.5vw, 2.6rem); }
  .craft__desc{ max-width: none; }
}


/* ============================================================
   FIGMA BUTTON SYSTEM  (catalyx.Space, frame 493:122)

   Four button shapes carry the whole page. The numbers below are
   lifted off the file rather than re-derived, which is why the
   pill padding is asymmetric: the arrow sits nearer its edge
   than the label does to its own.

     header CONTACT    radius 8, mono 400 13.6/19.72, +0.8px, caps
     View all projects arrow 40 on the LEFT, mono 600 18/27.2
     Talk to me        pill, ember + top sheen, mono 600 16/16
     Start a project   pill, white ground, 16/16

   Note: the file draws only the last of these four labels in
   Clash Display; the other three are Red Hat Mono. That reads as
   an oversight in the source rather than an intent, so all four
   are set in mono here and the Clash rule is left commented
   directly below it — swap the two lines to follow the file
   literally.
   ============================================================ */

/* --- shared pill -------------------------------------------- */
.v3 .btn{
  border-radius: 999px;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: 16px;
  font-weight: 600;
  line-height: 16px;
  letter-spacing: 0.2px;
}

.v3 .btn__arrow{
  width: 30px;
  height: 30px;
  font-size: 14px;
}

/* --- ember pill: "Talk to me" -------------------------------- */
.v3 .btn--primary{
  gap: 13.6px;
  padding: 13.6px 11.2px 13.6px 21.6px;
  color: #fff;
  background:
    linear-gradient(180deg, rgba(255,255,255,.35) 0%, rgba(255,255,255,0) 45%),
    var(--fp-ember, #FF5A1F);
}

.v3 .btn--primary .btn__arrow{
  background: #fff;
  color: var(--fp-ember, #FF5A1F);
}

/* --- white pill: "Start a project" --------------------------- */
.v3 .btn--white{
  gap: 12px;
  padding: 9.92px 9.6px 9.92px 17.6px;
  color: var(--fp-bone, #111114);
  background: #fff;
  font-weight: 600;
}
/* to follow the file literally, use this instead of the mono above:
.v3 .btn--white{ font-family: "Clash Display", system-ui, sans-serif; font-weight: 500; } */

.v3 .btn--white .btn__arrow{
  background: var(--fp-ember, #FF5A1F);
  color: #fff;
}

/* --- "View all projects": arrow leads, label follows ---------- */
.v3 .portfolio__viewall{
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: 18px;
  font-weight: 600;
  line-height: 27.2px;
  letter-spacing: 0.2px;
  color: var(--fp-bone, #111114);
}

.v3 .portfolio__viewall .circle-btn{
  width: 40px;
  height: 40px;
  flex: none;
}

/* --- header CONTACT: the one square-cornered button ----------- */
.rnav__contact{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 24px;
  border-radius: 8px;
  background: var(--fp-ember, #FF5A1F);
  color: #fff;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: 13.6px;
  font-weight: 400;
  line-height: 19.72px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  box-shadow: inset 0 -15px 20px rgba(255,255,255,.2);
}

.rnav__contact:hover,
.rnav__contact:focus-visible{
  color: #fff;
}

/* --- FAQ: the file carries no card behind this button --------- */
.v3 #v3-faq .faq__cta{
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.v3 #v3-faq .faq__cta .btn{
  min-height: 0;
  padding: 13.6px 11.2px 13.6px 21.6px;
  gap: 13.6px;
}

.v3 #v3-faq .faq__cta .btn__arrow{
  width: 30px;
  height: 30px;
  color: var(--fp-ember, #FF5A1F);
}

/* --- closing CTA heading is one plain line in the file -------- */
.v3 #v3-contact .cta__title .script,
.v3 #v3-contact .footer-sky__title .script{
  font-family: inherit;
  font-style: normal;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
}

/* ============================================================
   FIGMA TYPE SCALE  (catalyx.Space, frame 493:122)

   The file runs a two-step heading scale, not the open-ended
   fluid one this band shipped with:

     H1 / closing CTA   Inter Tight SemiBold  72 / 76
     every other H2     Inter Tight SemiBold  62 / normal (1.21)
     intro statement    Red Hat Mono Regular  48 / 64, caps
     eyebrow            Red Hat Mono SemiBold 14 / 18.85, +1.56

   Tracking is 0 on every heading in the file, so the negative
   letter-spacing the ramp used to carry is cleared rather than
   softened. The clamps keep small screens sane; their max ends
   are the drawn desktop values.
   ============================================================ */
:root{
  --h1: clamp(2.75rem, 5.2vw, 4.5rem);    /* caps at 72px */
  --h2: clamp(2.25rem, 4.2vw, 3.875rem);  /* caps at 62px */
}

.v3 h1, .v3 .h1{
  line-height: 1.056;
  letter-spacing: 0;
  font-weight: 600;
}

.v3 h2, .v3 .h2{
  line-height: 1.21;
  letter-spacing: 0;
  font-weight: 600;
}

/* --- intro statement: 48 / 64 in mono ------------------------ */
#intro .intro__statement{
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: clamp(1.5rem, 2.9vw, 3rem);
  line-height: 1.3333;
  font-weight: 400;
  letter-spacing: 0;
}

/* --- closing CTA: 72 / 76, no glow, 661px measure ------------ */
.v3 .footer-sky__title{
  max-width: 661px;
  font-size: clamp(2.75rem, 5.2vw, 4.5rem);
  line-height: 1.056;
  font-weight: 600;
  text-shadow: none;
}

/* the eyebrow here is the same mark as every other eyebrow on the
   page, so it gets the accent square too */
.v3 .footer-sky__eyebrow{
  display: inline-flex;
  align-items: center;
  gap: 7.8px;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: 14px;
  font-weight: 600;
  line-height: 18.85px;
  letter-spacing: 1.56px;
  text-transform: uppercase;
  color: #fff;
  text-shadow: none;
}

.v3 .footer-sky__eyebrow::before{
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 1px;
  background: var(--fp-ember, #FF5A1F);
  flex: none;
}

/* --- the ember pill carries no outer glow in the file --------- */
.v3 .btn--primary,
.v3 .btn--primary:hover{
  box-shadow: none;
}

/* ============================================================
   HEADING COLOUR INSIDE THE BAND

   Astra paints `body, h1..h6` with --ast-global-color-3 (#FAFAFA).
   That is a direct match on the heading element, so it outranks the
   dark colour .v3 sets on itself and only passes down by inheritance.
   The LIGHT SECTION HEADING READABILITY block above patched the
   symptom for h2, section by section, with !important — but h3 was
   never covered, so every card title on a paper ground (the first
   benefit card, the craft cards) rendered near-white on near-white.

   Letting headings inherit fixes the whole class in one rule: cards
   that set their own colour (the orange and dark benefits) keep their
   white text, and anything on paper picks up the band's ink.
   ============================================================ */
.v3 :is(h1, h2, h3, h4, h5, h6),
.v3 :is(h1, h2, h3, h4, h5, h6) .global-heading-inner{
  color: inherit;
}

/* ============================================================
   TESTIMONIALS HEAD
   The file gives this section the same eyebrow mark as every other
   one, and sets the whole heading in a single face — no script word.
   ============================================================ */
.v3 .testimonials .container{
  text-align: center;
}

.v3 .testimonials__eyebrow{
  margin: 0 auto .75rem;
  justify-content: center;
  display: inline-flex;
  align-items: center;
  gap: 7.8px;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size: 14px;
  font-weight: 600;
  line-height: 18.85px;
  letter-spacing: 1.56px;
  text-transform: uppercase;
  color: var(--fp-bone, #111114);
}

.v3 .testimonials__eyebrow::before{
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 1px;
  background: var(--fp-ember, #FF5A1F);
  flex: none;
}

.v3 .testimonials h2 .script{
  font-family: inherit !important;
  font-style: normal !important;
  font-size: inherit !important;
  color: inherit !important;
}

/* the about title is one line in the file, not two */
@media (min-width: 1100px){
  .v3 #v3-about .section-head h2,
  .v3 #v3-about h2{
    max-width: none;
    white-space: nowrap;
  }
}

/* ============================================================
   THE CRAFT + SERVICES SIT OUTSIDE .v3

   #services and #capabilities are siblings of the .v3 band, so the
   heading-inherit rule above never reached them and the two cards
   on light grounds (#CCEAFA, #C6F24E) kept Astra's near-white
   heading colour. Same repair, extended to that section.
   ============================================================ */
.craft :is(h1, h2, h3, h4, h5, h6),
.craft :is(h1, h2, h3, h4, h5, h6) .global-heading-inner{
  color: inherit;
}

/* The card title is Inter Tight SemiBold 96 / 100 with flat
   tracking — the older note in this file recorded it as Clash
   Display Medium at -2.4px, which the file no longer shows. */
.craft__title{
  font-weight: 600;
  letter-spacing: 0;
}

/* --- the closing heading carries no accent word in the file ---
   Repeating the selector the LIGHT SECTION HEADING READABILITY
   block uses, so this wins on source order rather than by piling
   on more specificity. */
.v3 :is(.portfolio, #v3-about, #v3-services, #v3-clients, #v3-benefits, #v3-faq, .testimonials) h2 .script{
  color: inherit !important;
  font-family: inherit !important;
  font-style: normal !important;
}
/* ============================================================
   SCENE 06 \u2014 THE HYBRID (SPLIT MERGE)   figma 493:353

   The only section in the file with no counterpart on the site.
   Two full-height grounds sit closed over a single line, and part
   on scroll to uncover it.

     left ground   #f4faff, Inter Tight SemiBold 60.8 / 63.84, -1px, #2d2d2d
     right ground  #0c0c0c, same type, right-aligned, white
     the line      Inter Tight SemiBold 88.3 / 92.736,
                   #fafafa over #d96c2c on the second line

   This sits inside .v3, which carries overflow-x:hidden \u2014 that makes
   an ancestor scroll container and kills position:sticky, so the hold
   is done with a ScrollTrigger pin (what #services and #capabilities
   already use) rather than sticky. The selectors below are doubled up
   under .v3 because the band sets its own type on p/h2 and would
   otherwise win on specificity.
   ============================================================ */
.hybrid{
  position: relative;
  background: #0c0c0c;
}

.hybrid__stage{
  position: relative;
  height: 100vh;
  min-height: 34rem;
  overflow: hidden;
}

/* --- the line the two grounds are hiding --------------------- */
.hybrid__reveal{
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 0 6vw;
  text-align: center;
}

.v3 .hybrid__headline,
.hybrid__headline{
  margin: 0;
  max-width: none;
  font-family: var(--fp-font-grotesque, "Inter Tight", system-ui, sans-serif);
  font-weight: 600;
  font-size: clamp(2rem, 4.6vw, 5.52rem);
  line-height: 1.05;
  letter-spacing: 0;
  color: #fafafa;
  text-transform: none;
}

.hybrid__line{ display: block; }
.v3 .hybrid__line--accent,
.hybrid__line--accent{ color: #d96c2c; }

/* --- the two grounds ----------------------------------------- */
.hybrid__half{
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50.2%;            /* the .2 keeps a hairline from opening at the seam */
  display: flex;
  align-items: center;
  will-change: transform;
}

.hybrid__half--design{
  left: 0;
  justify-content: flex-start;
  padding-left: 8vw;
  padding-right: 2vw;
  background: #f4faff;
}

.hybrid__half--build{
  right: 0;
  justify-content: flex-end;
  padding-right: 8vw;
  padding-left: 2vw;
  background: #0c0c0c;
  text-align: right;
}

.v3 .hybrid__stack,
.hybrid__stack{
  margin: 0;
  max-width: none;
  font-family: var(--fp-font-grotesque, "Inter Tight", system-ui, sans-serif);
  font-weight: 600;
  font-size: clamp(1.35rem, 3.17vw, 3.8rem);
  line-height: 1.05;
  letter-spacing: -1px;
}

.v3 .hybrid__half--design .hybrid__stack{ color: #2d2d2d; }
.v3 .hybrid__half--build  .hybrid__stack{ color: #fff; }

/* --- no motion: hold the closed state ------------------------ */
@media (prefers-reduced-motion: reduce){
  .hybrid__stage{ height: 100vh; }
}

@media (max-width: 720px){
  .hybrid__half--design{ padding-left: 6vw; }
  .hybrid__half--build{ padding-right: 6vw; }
}

/* ============================================================
   FLIPSVC GROUND
   style.css grounds this section in --fp-ink (#FAFAF7, the paper
   tone). Requested as plain white.
   ============================================================ */
.flipsvc{
  background: #ffffff;
}


/* ============================================================
   GLOBAL BUTTON STYLING (Matched to .rnav__contact)
   ============================================================ */
.v3 .btn,
.v3 .btn--primary,
.v3 .btn--white,
.v3 .footer-sky__button,
.flyg__text .fp-btn,
.fp-btn,
.pj__cta{
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  padding: 10px 24px !important;
  min-height: unset !important;
  min-width: unset !important;
  border-radius: 8px !important;
  background: var(--fp-ember, #FF5A1F) !important;
  border: none !important;
  color: #fff !important;
  font-family: "Red Hat Mono", ui-monospace, SFMono-Regular, monospace !important;
  font-size: 13.6px !important;
  font-weight: 500 !important;
  line-height: 19.72px !important;
  letter-spacing: 0.8px !important;
  text-transform: uppercase !important;
  text-decoration: none !important;
  box-shadow: inset 0 -15px 20px rgba(255,255,255,.2) !important;
  transition: transform 0.25s ease, opacity 0.25s ease, background 0.25s ease !important;
}

.v3 .btn:hover,
.v3 .btn--primary:hover,
.v3 .btn--white:hover,
.v3 .footer-sky__button:hover,
.flyg__text .fp-btn:hover,
.fp-btn:hover,
.pj__cta:hover{
  color: #fff !important;
  background: var(--fp-ember, #FF5A1F) !important;
  border: none !important;
  transform: translateY(-2px) !important;
  opacity: 0.95 !important;
}

.v3 .btn:focus-visible,
.v3 .btn--primary:focus-visible,
.v3 .btn--white:focus-visible,
.v3 .footer-sky__button:focus-visible,
.flyg__text .fp-btn:focus-visible,
.fp-btn:focus-visible,
.pj__cta:focus-visible{
  outline: 2px solid #fff !important;
  outline-offset: 3px !important;
  color: #fff !important;
}

/* Remove circular backgrounds and render sleek SVG arrow */
.v3 .btn .btn__arrow,
.v3 .footer-sky__button .btn__arrow,
.flyg__text .fp-btn span,
.fp-btn span,
.pj__cta .btn__arrow{
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: auto !important;
  height: auto !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  color: #fff !important;
  font-size: 14px !important;
  line-height: 1 !important;
  padding: 0 !important;
  margin: 0 !important;
  box-shadow: none !important;
  transform: none !important;
  transition: transform 0.25s ease !important;
}

.v3 .btn .btn__arrow svg,
.v3 .footer-sky__button .btn__arrow svg,
.flyg__text .fp-btn span svg,
.fp-btn span svg,
.pj__cta .btn__arrow svg{
  display: inline-block !important;
  width: 14px !important;
  height: 14px !important;
  stroke: currentColor !important;
  stroke-width: 2.5 !important;
  fill: none !important;
  vertical-align: middle !important;
  margin-left: 2px !important;
}

.v3 .btn:hover .btn__arrow,
.v3 .footer-sky__button:hover .btn__arrow,
.flyg__text .fp-btn:hover span,
.fp-btn:hover span,
.pj__cta:hover .btn__arrow{
  transform: translateX(3px) !important;
}

/* ============================================================
   WHITE FOOTER BUTTON (Image 1 match)
   ============================================================ */
.v3 .site-footer-sky .footer-sky__button,
.v3 .footer-sky__button,
.v3 .site-footer-sky .btn--white,
.site-footer-sky .footer-sky__button{
  background: #ffffff !important;
  color: #111114 !important;
  border-radius: 8px !important;
  border: none !important;
  box-shadow: 0 4px 18px rgba(17, 17, 20, 0.08) !important;
}

.v3 .site-footer-sky .footer-sky__button:hover,
.v3 .footer-sky__button:hover,
.v3 .site-footer-sky .btn--white:hover,
.site-footer-sky .footer-sky__button:hover{
  background: #f7f9fa !important;
  color: #111114 !important;
  border: none !important;
  transform: translateY(-2px) !important;
  opacity: 1 !important;
}

.v3 .site-footer-sky .footer-sky__button .btn__arrow,
.v3 .footer-sky__button .btn__arrow,
.site-footer-sky .footer-sky__button .btn__arrow{
  color: #111114 !important;
}

.v3 .site-footer-sky .footer-sky__button .btn__arrow svg,
.v3 .footer-sky__button .btn__arrow svg,
.site-footer-sky .footer-sky__button .btn__arrow svg{
  stroke: #111114 !important;
}

/* ============================================================
   08 · BENEFITS OF HIRING ME - ACCENT COLOR PICKER SYNC
   Matches color picker changes across the 3 benefit cards:
   1) Speed bars in "Live in weeks, not months"
   2) Vibrant gradient on "Design + Code, one person"
   3) Deep tone on "Support after launch"
   4) Soft tint on the mockup panels (.img-slot)
   ============================================================ */
.v3 .benefit__speed span {
  background: var(--ember, var(--accent, #FF5A1F)) !important;
  transition: background-color 0.4s ease, opacity 0.4s ease;
}

.v3 .benefit--orange {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0) 40%),
    linear-gradient(160deg, var(--benefit-light, color-mix(in srgb, var(--ember, #FF5A1F) 82%, #ffffff)), var(--ember, #FF5A1F) 55%, var(--benefit-deep, color-mix(in srgb, var(--ember, #FF5A1F) 80%, #000000))) !important;
  background-color: var(--ember, #FF5A1F);
  transition: background 0.4s ease, background-color 0.4s ease;
}

.v3 .benefit--dark {
  background: var(--craft-card-bone, #111114) !important;
  transition: background 0.4s ease, background-color 0.4s ease;
}

.v3 .benefit .img-slot {
  background: linear-gradient(140deg, #F1F1EC, var(--accent-soft, color-mix(in srgb, var(--ember, #FF5A1F) 14%, #ffffff))) !important;
  transition: background 0.4s ease;
}

/* ============================================================
   INTERACTIVE ELEMENTS - ACCENT COLOR PICKER SYNC
   1) Circle action buttons (.circle-btn, .work-card__go, .portfolio__viewall .circle-btn)
   2) Active pagination dots (.dots span.is-active)
   3) Work card category tags (.work-card__tags .tag)
   4) Testimonial card arrow links (.tm-card__link)
   ============================================================ */
.v3 .circle-btn,
.v3 .portfolio__viewall .circle-btn,
.v3 .work-card__go,
.v3 .work-card:hover .work-card__go {
  background: var(--ember, var(--accent, #FF5A1F)) !important;
  color: #FFFFFF !important;
  transition: transform var(--dur) var(--ease-out), background-color 0.4s ease, opacity var(--dur) var(--ease-out) !important;
}

.v3 .dots span.is-active,
.v3 .work-card .dots span.is-active {
  background: var(--ember, var(--accent, #FF5A1F)) !important;
  transition: background-color 0.4s ease;
}

.v3 .work-card__tags .tag,
.v3 .work-card .tag {
  background: var(--ember, var(--accent, #FF5A1F)) !important;
  color: #FFFFFF !important;
  transition: background-color 0.4s ease;
}

.v3 .tm-card__link:hover,
.v3 .tm-card__link:focus-visible,
.v3 .tm-card:hover .tm-card__link {
  background: var(--ember, var(--accent, #FF5A1F)) !important;
  color: #FFFFFF !important;
  transition: background-color 0.4s ease, color 0.4s ease;
}

/* ============================================================
   HIDE NATIVE SIDE SCROLLBAR (Cross-browser)
   ============================================================ */
html,
body,
#page,
.site,
.ast-container {
  scrollbar-width: none !important;
  -ms-overflow-style: none !important;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar,
#page::-webkit-scrollbar,
.site::-webkit-scrollbar,
.ast-container::-webkit-scrollbar {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
  background: transparent !important;
}

/* ============================================================
   TOP SCROLLER IN FIXED HEADER (.rnav)
   ============================================================ */
.rnav__scroller {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: rgba(0, 0, 0, 0.06);
  z-index: 1000;
  cursor: pointer;
  pointer-events: auto;
  transition: height 0.2s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.3s ease;
}

.rnav.is-glass .rnav__scroller {
  background: rgba(0, 0, 0, 0.08);
}

.rnav.is-glass.rnav--on-hero .rnav__scroller {
  background: rgba(255, 255, 255, 0.16);
}

.rnav__scroller:hover {
  height: 6px;
}

.rnav__scroller-bar {
  height: 100%;
  width: 0%;
  background: var(--ember, var(--accent, #FF5A1F));
  box-shadow: 0 0 10px var(--ember, rgba(255, 90, 31, 0.65)), 0 0 2px var(--ember, #FF5A1F);
  border-radius: 0 2px 2px 0;
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
  will-change: width;
}


/* ============================================================
   06b - PROCESS BENTO
   One cell per pose plus one accent intro tile. The areas map
   holds exactly 14 cells (no filler): 4 x 5 on desktop, 2 x 10
   below 1024px. The three landscape poses (w1-w3) take the wide
   cells; deploy day (d) is the 2 x 2 lead.
   ============================================================ */
#v3-skills .section-head{ justify-content: center; }

.v3 .poses__title{
  text-align: center;
  margin: 0 auto clamp(2rem, 5vw, 3.5rem);
  max-width: 18ch;
}

.v3 .poses__grid{
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: clamp(200px, 22vw, 310px);
  grid-template-areas:
    "t  d  d  a"
    "b  d  d  c"
    "w1 w1 e  f"
    "g  h  w2 w2"
    "w3 w3 i  j";
  gap: clamp(0.6rem, 1.2vw, 1rem);
}

.v3 .poses__cell{
  position: relative;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 1px solid #E4E2DB;
  border-radius: 24px;
  background: #FFFFFF;
}

.v3 .poses__cell img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* the poses sit on white, so multiply lets them take each cell's ground */
  mix-blend-mode: multiply;
}


/* ground variety: paper-recessed and accent-tint cells among the white */
.v3 .poses__cell--d{ background: var(--accent-soft); border-color: transparent; }
.v3 .poses__cell--c,
.v3 .poses__cell--w1,
.v3 .poses__cell--g,
.v3 .poses__cell--j{ background: #F1F1EC; border-color: transparent; }

.v3 .poses__cell--intro{ grid-area: t; }
.v3 .poses__cell--a{ grid-area: a; }
.v3 .poses__cell--b{ grid-area: b; }
.v3 .poses__cell--c{ grid-area: c; }
.v3 .poses__cell--d{ grid-area: d; }
.v3 .poses__cell--e{ grid-area: e; }
.v3 .poses__cell--f{ grid-area: f; }
.v3 .poses__cell--g{ grid-area: g; }
.v3 .poses__cell--h{ grid-area: h; }
.v3 .poses__cell--i{ grid-area: i; }
.v3 .poses__cell--j{ grid-area: j; }
.v3 .poses__cell--w1{ grid-area: w1; }
.v3 .poses__cell--w2{ grid-area: w2; }
.v3 .poses__cell--w3{ grid-area: w3; }

/* the accent tile: solid accent ground, ink label (white on the
   accent falls under 4.5:1 at these sizes) */
.v3 .poses__cell--intro{
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1.1rem, 2vw, 1.75rem);
  background: var(--accent);
  border-color: transparent;
  color: #111114;
}

.v3 .poses__intro-head{
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.3vw, 2.25rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.v3 .poses__intro-copy{
  margin: 0;
  max-width: 30ch;
  font-size: 0.85rem;
  line-height: 1.5;
}

@media (max-width: 1024px){
  .v3 .poses__grid{
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: clamp(170px, 42vw, 340px);
    grid-template-areas:
      "t  a"
      "d  d"
      "d  d"
      "b  c"
      "w1 w1"
      "e  f"
      "w2 w2"
      "g  h"
      "w3 w3"
      "i  j";
  }
  .v3 .poses__cell{ border-radius: 18px; }
}

@media (max-width: 520px){
  .v3 .poses__cell--intro{ padding: 0.9rem; }
  .v3 .poses__intro-head{ font-size: 1.15rem; }
  .v3 .poses__intro-copy{ font-size: 0.7rem; line-height: 1.4; }
}

@media (prefers-reduced-motion: reduce){
  .v3 .poses__cell img{ transition: none; }
  .v3 .poses__cell:hover img{ transform: none; }
}

/* bento intro tile: link through to the full workflow page */
.v3 .poses__intro-link{
  align-self:flex-start;
  font-family:"Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size:0.8rem;
  font-weight:600;
  color:#111114;
  text-decoration:underline;
  text-underline-offset:4px;
  text-decoration-thickness:1px;
}
.v3 .poses__intro-link:hover,
.v3 .poses__intro-link:focus-visible{ text-decoration-thickness:2px; color:#111114; }
.v3 .poses__intro-link:focus-visible{ outline:2px solid #111114; outline-offset:3px; }

/* bento: button through to the full workflow page */
.v3 .poses__more{ display:flex; justify-content:center; margin-top:clamp(1.75rem, 3.5vw, 2.75rem); }

/* skills bento: hover ring and the Lottie layer (js/poses-bento.js) */
.v3 .poses__cell img{ transform-origin:50% 60%; }
.v3 .poses__ring{
  position:absolute; left:50%; top:50%;
  width:58%; aspect-ratio:1;
  translate:-50% -50%;
  border:3px solid var(--accent);
  border-radius:50%;
  opacity:0;
  pointer-events:none;
}
.v3 .poses__lottie{ position:absolute; inset:0; }
.v3 .poses__lottie svg{ mix-blend-mode:multiply; }
.v3 .poses__cell.has-lottie img{ opacity:0; }

/* skills bento, desktop: 6 x 4 so the whole grid fits one screen while it
   pins and the tiles fly in (js/poses-bento.js) */
.v3 .poses{ overflow:clip; }
@media (min-width: 1025px){
  .v3 .poses__grid{
    --rh: clamp(120px, calc((100vh - 140px) / 4), 270px);
    width: min(100%, calc(var(--rh) * 6 * 1.45 + 60px));
    margin-inline: auto;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    grid-auto-rows: var(--rh);
    grid-template-areas:
      "t  t  d  d  a  a"
      "t  t  d  d  b  c"
      "w1 w1 e  f  w2 w2"
      "g  h  w3 w3 i  j";
  }
  .v3 .poses__intro-head{ font-size: clamp(1.8rem, 2.8vw, 2.8rem); }
  .v3 .poses__intro-copy{ font-size: 0.95rem; }
}

/* skills bento, desktop: heading and grid pin together under the nav,
   so the head is compact and the rows share what is left of the screen */
@media (min-width: 1025px){
  #v3-skills .section-head{ margin-bottom: 1rem; padding-top: 0; }
  .v3 .poses__title{ margin-bottom: clamp(1.25rem, 2.2vw, 1.75rem); }
}

/* flying tiles pass under the heading, never over it */
#v3-skills .section-head,
#v3-skills .poses__title{ position: relative; z-index: 2; }
#v3-skills .poses__grid{ position: relative; z-index: 1; }

/* skills bento: the section heading lives in the intro tile so the cards
   can use the whole screen height while the grid pins */
.v3 .poses__intro-label{
  display:inline-flex; align-items:center; gap:8px;
  margin-bottom:0.9rem;
  font-family:"Red Hat Mono", ui-monospace, SFMono-Regular, monospace;
  font-size:12px; font-weight:600; letter-spacing:0.14em; text-transform:uppercase;
  color:#111114;
}
.v3 .poses__intro-label::before{ content:""; width:10px; height:10px; border-radius:2px; background:#111114; flex:none; }
.v3 h2.poses__intro-head{ margin:0; color:#111114; line-height:1.02; }
@media (min-width: 1025px){
  .v3 h2.poses__intro-head{ font-size: clamp(2rem, 3.1vw, 3.4rem); max-width: 10ch; }
}
@media (max-width: 1024px){
  .v3 .poses__grid{
    grid-template-rows: auto;
    grid-template-areas:
      "t  t"
      "d  d"
      "d  d"
      "a  a"
      "b  c"
      "w1 w1"
      "e  f"
      "w2 w2"
      "g  h"
      "w3 w3"
      "i  j";
  }
  .v3 .poses__cell--intro{ gap: 1.5rem; }
  .v3 h2.poses__intro-head{ font-size: clamp(1.8rem, 7vw, 2.6rem); }
  .v3 .poses__intro-copy{ font-size: 0.85rem; }
}

/* ============================================================
   skills bento: video cards (15 clips + the intro tile = 16 cells)
   ============================================================ */
.v3 .poses__cell{ cursor: pointer; }
.v3 .poses__cell--intro{ cursor: default; }
.v3 .poses__video{
  display:block;
  width:100%; height:100%;
  object-fit:contain;
  /* the clips sit on near-white, so multiply lets them take each card's ground */
  mix-blend-mode:multiply;
  background:transparent;
  pointer-events:none;
}
.v3 .poses__cell--k{ grid-area:k; }
.v3 .poses__cell--l{ grid-area:l; }
.v3 .poses__cell--m{ grid-area:m; }
.v3 .poses__cell--m,
.v3 .poses__cell--e{ background:#F1F1EC; border-color:transparent; }

@media (min-width: 1025px){
  .v3 .poses__grid{
    grid-template-areas:
      "t  t  d  d  a  b"
      "t  t  d  d  c  e"
      "w1 w1 f  g  h  i"
      "j  k  w2 w2 l  m";
  }
}
@media (max-width: 1024px){
  .v3 .poses__grid{
    grid-template-areas:
      "t  t"
      "d  d"
      "d  d"
      "a  b"
      "c  e"
      "w1 w1"
      "f  g"
      "h  i"
      "j  k"
      "w2 w2"
      "l  m";
  }
}

/* video cards share the clips' own near-white ground so no frame edge shows
   (video layers do not reliably take mix-blend-mode) */
.v3 .poses__cell:not(.poses__cell--intro){ background:#FDFDFD; border-color:#E4E2DB; }
.v3 .poses__video{ mix-blend-mode:normal; }

/* skills bento: four square cards a row on desktop, two on smaller
   screens. Square cells match the square clips; the row height comes from
   the cards' own aspect ratio now that the grid no longer pins. */
.v3 .poses__cell:not(.poses__cell--intro){ aspect-ratio: 1; }
@media (min-width: 1025px){
  .v3 .poses__grid{
    width: 100%;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: auto;
    grid-template-areas:
      "t  t  d  d"
      "a  b  d  d"
      "c  e  f  g"
      "w1 h  i  j"
      "k  w2 l  m";
  }
  .v3 .poses__cell--intro{ min-height: 0; }
}
@media (max-width: 1024px){
  .v3 .poses__grid{
    grid-auto-rows: auto;
    grid-template-areas:
      "t  t"
      "d  d"
      "d  d"
      "a  b"
      "c  e"
      "f  g"
      "w1 h"
      "i  j"
      "k  w2"
      "l  m";
  }
}

/* desktop: every row as tall as a square card, so the 2 x 2 Deploy card
   lines up with its neighbours and the intro tile matches the row */
@media (min-width: 1025px){
  .v3 .poses__grid{ grid-auto-rows: 1fr; }
  .v3 .poses__cell--d{ aspect-ratio: auto; }
}

/* intro tile: white type on the accent */
.v3 .poses__cell--intro,
.v3 .poses__intro-label,
.v3 h2.poses__intro-head,
.v3 .poses__intro-copy{ color:#FFFFFF; }
.v3 .poses__intro-label::before{ background:#FFFFFF; }
