/* ============================================================================
   THE SITE FOOTER, for pages that do not load v3's global stylesheets
   ----------------------------------------------------------------------------
   v3's own rules, not a re-creation. Amanda: "Why not just use the existing one
   to keep the consistency."

   The project pages cannot load v3's styles.css: it carries a global reset and
   would restyle five hand-built pages. So the rules are scoped under .master-footer
   instead, and the tokens they read are redeclared there rather than on :root.
   Same declarations, same measured numbers, no leakage.

   The scope class goes on a WRAPPER, never on the component's own root element:
   every rule here is scoped as a DESCENDANT, and a descendant selector does not
   match the element carrying the class.

   Rules are collected BY SELECTOR from the whole of each source file, not from
   one banner-delimited block -- v3 keeps its mobile overrides in a shared @media
   block far from the component they belong to, and missing them is how the
   footer headline came to overflow a phone.

   The blocks are in v3's own load order -- styles.css, type-system.css,
   chrome.css -- because that order decides the winner between two equally
   specific single-class rules.

   GENERATED by scripts/gen-master-chrome.py. Regenerate; do not hand-edit.
   ========================================================================== */
.master-footer {

  /* ============================================================
     MASTER COLOUR
     ------------------------------------------------------------
     Two ramps of four, and nothing repeated. Everything that used to be
     --black, --ink and --line-strong was the same #111111 under three names;
     it is one token now.

     BLACK serves light surfaces: 1 is the ink, the outline and the primary
     dark ground; 2 is a raised panel on top of 1; 3 and 4 are secondary and
     tertiary text.
     WHITE serves dark surfaces, and carries #F8FAFC's cool cast down the ramp
     so greys on this site are never a flat neutral.

     Contrast, measured: black-3 is 5.33:1 on white-1 and black-4 is 3.45:1,
     so secondary text passes AA for body and tertiary passes for large text
     and UI. white-3 is 8.63:1 on black-1 and white-4 is 4.87:1.
     ============================================================ */
  --black-1: #111111;   /* ink · outline · primary dark ground   */
  --black-2: #1C1C1C;   /* secondary dark ground, raised on 1    */
  --black-3: #6B6B6B;   /* secondary text on a light ground      */
  --black-4: #8A8A8A;   /* tertiary text, meta, disabled         */

  --white-1: #FFFFFF;   /* primary light ground                  */
  --white-2: #F8FAFC;   /* secondary light ground                */
  --white-3: #A9B0B9;   /* secondary text on a dark ground       */
  --white-4: #7A828E;   /* tertiary text on a dark ground        */

  /* ---- three surface utilities ----
     Not colours in the ramps above, and not duplicates of them: a hairline is
     translucent so it rides whatever is underneath, and --fill is the one grey
     allowed as a fill inside an outlined container. */
  --line: rgba(17, 17, 17, 0.18);        /* hairline on a light ground */
  --line-light: rgba(255, 255, 255, 0.35); /* hairline on a dark ground */
  --fill: #ECECEC;                       /* progress track, filled bar, nested panel */

  --container-max: 1720px;
  --gutter: clamp(20px, 5.2vw, 100px);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --radius-media: clamp(6px, 0.55vw, 8px);


  /* from styles.css's body rule, which these components inherit from on v3 */
  font-family: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--black-1);
  line-height: 1.2;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.master-footer *,
.master-footer *::before,
.master-footer *::after { box-sizing: border-box; }
.master-footer * { margin: 0; padding: 0; }
.master-footer img { display: block; max-width: 100%; }
.master-footer a { color: inherit; text-decoration: none; }
.master-footer ul { list-style: none; }

/* ---- the host page's own rules stop here ---------------------------------
   THIS BLOCK IS LOAD-BEARING. These pages were built before this chrome existed
   and they use the same class names: aspire, identity and nobi each define their
   own .footer, and nobi defines .footer__legal. Their rules were landing on v3's
   markup -- aspire's `.footer { background: var(--navy) }` put a navy band across
   the bottom of the site footer, and nobi's `.footer__legal { color: var(--muted) }`
   painted the copyright line dark on dark until it disappeared.

   The scope class is doubled so this sits at (0,2,0): it beats any single-class
   rule a host page has, and loses to every rule below it in this file, which is
   also (0,2,0) but comes later. So it wipes the host's declarations and then v3's
   own put back exactly what belongs. Placed FIRST for that reason. */
.master-footer.master-footer *,
.master-footer.master-footer *::before,
.master-footer.master-footer *::after {
  background: none;
  border: 0;
  box-shadow: none;
  text-shadow: none;
  color: inherit;
  opacity: 1;
  filter: none;
  transform: none;
  animation: none;
  float: none;
  position: static;
  min-height: 0;
  max-width: none;
  text-align: inherit;
  text-transform: none;
  font-style: normal;
  font-variant: normal;
}

/* ==== styles.css ========================================================= */
.master-footer .container {
  width: 100%;
  max-width: calc(var(--container-max) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}.master-footer .contact {
  background: var(--black-1);
  color: var(--white-1);
  padding-block: clamp(64px, 8vw, 150px) clamp(40px, 4vw, 60px);
}.master-footer .contact__info {
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 6vw, 100px);
}.master-footer .contact__title {
  font-weight: 500;
  /* one line on desktop/tablet (sized to fit the container); wraps on mobile */
  font-size: clamp(56px, 10.6vw, 206px);
  line-height: 0.98;
  letter-spacing: -0.045em;
  white-space: nowrap;
}.master-footer .contact__details {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  gap: clamp(40px, 5.5vw, 80px);
}.master-footer .contact__email-wrap { position: relative; }.master-footer .contact__email {
  display: inline-flex;
  align-items: center;
  gap: 0.32em;
  font: inherit;
  font-weight: 500;
  font-size: clamp(22px, 2.6vw, 48px);
  letter-spacing: -0.03em;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}.master-footer .copy-icon {
  width: 0.62em;
  height: 0.62em;
  flex: none;
  opacity: 0.85;
  transition: opacity 0.3s var(--ease);
}.master-footer .contact__email:hover .copy-icon { opacity: 1; }.master-footer .contact__email-text {
  position: relative;
}.master-footer .contact__email-text::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -0.12em;
  height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease-out);
}.master-footer .contact__email:hover .contact__email-text::after { transform: scaleX(1); }.master-footer .copy-toast {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.28);
  color: var(--white-1);
  font-size: clamp(12px, 1vw, 15px);
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease-out);
}.master-footer .copy-toast::before {
  content: "";
  width: 13px;
  height: 13px;
  flex: none;
  background: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M5 13l4 4L19 7' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}.master-footer .copy-toast.is-shown {
  opacity: 1;
  transform: translateY(0);
}.master-footer .contact__links {
  display: flex;
  gap: clamp(40px, 5.5vw, 80px);   /* matches the email↔links gap */
}.master-footer .contact__col {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 1.6vw, 40px);
}.master-footer .footer {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-top: clamp(60px, 8vw, 150px);
}.master-footer .footer__info { display: flex; flex-direction: column; gap: 4px; }.master-footer .footer__name { font-weight: 500; font-size: clamp(14px, 1vw, 20px); letter-spacing: -0.02em; }.master-footer .footer__detail { font-weight: 400; font-size: clamp(14px, 1vw, 20px); letter-spacing: -0.02em; opacity: 0.85; }.master-footer .footer__year { font-weight: 500; font-size: clamp(20px, 1.5vw, 28px); letter-spacing: -0.02em; }
@media (max-width: 760px) {.master-footer .contact__title { white-space: normal; }.master-footer .contact__details { flex-direction: column; gap: 32px; }.master-footer .contact__links { flex-direction: column; gap: 24px; }.master-footer .contact__email-text::after { transform: scaleX(1); }.master-footer .footer { flex-direction: column; align-items: flex-start; gap: 12px; }.master-footer .footer__year { font-size: 14px; }

}


/* ==== type-system.css, entire ============================================ */
/* ============================================================
   Amanda Idris — Portfolio Typography System
   Derived from the Case Study page (Figma desktop 1920).
   A single, reusable text-sizing guide for the whole portfolio.

   HOW TO USE
   - Load this file AFTER styles.css on any page.
   - Apply a role class to a text element: class="t-h3", "t-body", …
   - Or read the --fs-* / --lh-* / --tracking-* tokens directly in CSS.

   The raw Figma sizes (92, 72, 64, 56, 48, 40, 32, 28, 24, 20, 19,
   18, 16, 15, 14) are rationalised into the 13 steps below. Every
   step is fluid: it scales between a mobile min and the Figma max
   via clamp(), reaching its max around a ~1600px viewport.
   ============================================================ */.master-footer {
  /* ---- Type family (shared with the rest of the site) ---- */
  --font-sans: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* ---- Display & headings ---- */
  --fs-display-1: 5rem;     /* 80px  Display 1 · Medium · hero metrics */
  --fs-display-2: 4.375rem; /* 70px  Display 2 · Medium · big stat numbers */
  --fs-h1:      clamp(2.5rem, 1.73rem + 2.4vw, 4rem);      /* 40 → 64  page section */
  --fs-h2:      clamp(2.125rem, 1.45rem + 2.1vw, 3.5rem);  /* 34 → 56  case-study title */
  --fs-h3:      clamp(1.875rem, 1.39rem + 1.5vw, 3rem);    /* 30 → 48  section heading */
  --fs-h4:      clamp(1.625rem, 1.3rem + 1.0vw, 2.5rem);   /* 26 → 40  card / project title */
  --fs-h5:      clamp(1.5rem, 1.31rem + 0.6vw, 2rem);      /* 24 → 32  sub-section heading */
  --fs-h6:      clamp(1.375rem, 1.25rem + 0.39vw, 1.75rem);/* 22 → 28  block / tab title */

  /* ---- Body & UI (fixed sizes) ---- */
  --fs-body-lg:   1.125rem;  /* 18px  Body Large · lead / body */
  --fs-body:      1rem;      /* 16px  Body Normal · default body / nav */
  --fs-body-sm:   0.875rem;  /* 14px  Body small · dense body / captions */
  --fs-body-tiny: 0.6875rem; /* 11px  Body Tiny · meta labels */
  --fs-eyebrow-1: 0.8125rem; /* 13px  Eyebrow 1 · SemiBold · uppercase · +0.07em */
  --fs-eyebrow-2: 0.6875rem; /* 11px  Eyebrow 2 · SemiBold · uppercase · +0.06em */

  /* ---- Line heights ---- */
  --lh-display: 0.98;   /* huge metrics, single line */
  --lh-tight:   1.04;   /* headings */
  --lh-snug:    1.18;   /* sub-headings, tab titles */
  --lh-normal:  1.45;   /* body copy */
  --lh-label:   1.25;   /* labels, eyebrows */

  /* ---- Letter spacing ---- */
  --tracking-display: -0.04em;
  --tracking-heading: -0.03em;
  --tracking-snug:    -0.02em;
  --tracking-body:    -0.01em;
  --tracking-wide:     0.06em;  /* eyebrow 2 / all-caps */
  --tracking-wider:    0.07em;  /* eyebrow 1 */

  /* ---- Weights (Figtree: 300 400 500 600 700) ---- */
  --fw-light:    300;
  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;
}

/* ============================================================
   ROLE CLASSES
   Each sets size + weight + leading + tracking. Override weight
   per-instance with the .fw-* helpers below where the design
   diverges (e.g. a Light body paragraph).
   ============================================================ */.master-footer .t-display-1,
.master-footer .t-display-2,
.master-footer .t-h1,
.master-footer .t-h2,
.master-footer .t-h3,
.master-footer .t-h4,
.master-footer .t-h5,
.master-footer .t-h6 {
  font-family: var(--font-sans);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-heading);
  line-height: var(--lh-tight);
}.master-footer .t-display-1 { font-size: var(--fs-display-1); line-height: var(--lh-display); letter-spacing: var(--tracking-display); }.master-footer .t-display-2 { font-size: var(--fs-display-2); line-height: var(--lh-display); letter-spacing: var(--tracking-display); }.master-footer .t-h1 { font-size: var(--fs-h1); letter-spacing: var(--tracking-display); }.master-footer .t-h2 { font-size: var(--fs-h2); }.master-footer .t-h3 { font-size: var(--fs-h3); }.master-footer .t-h4 { font-size: var(--fs-h4); }.master-footer .t-h5 { font-size: var(--fs-h5); line-height: var(--lh-snug); letter-spacing: var(--tracking-snug); }.master-footer .t-h6 { font-size: var(--fs-h6); line-height: var(--lh-snug); letter-spacing: var(--tracking-snug); font-weight: var(--fw-semibold); }.master-footer .t-body-lg,
.master-footer .t-body,
.master-footer .t-body-sm,
.master-footer .t-body-tiny,
.master-footer .t-eyebrow-1,
.master-footer .t-eyebrow-2 {
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  letter-spacing: var(--tracking-body);
  line-height: var(--lh-normal);
}.master-footer .t-body-lg { font-size: var(--fs-body-lg); }.master-footer .t-body { font-size: var(--fs-body); }.master-footer .t-body-sm { font-size: var(--fs-body-sm); }.master-footer .t-body-tiny { font-size: var(--fs-body-tiny); font-weight: var(--fw-medium); line-height: var(--lh-label); }.master-footer .t-eyebrow-1 {
  font-size: var(--fs-eyebrow-1);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-label);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
}.master-footer .t-eyebrow-2 {
  font-size: var(--fs-eyebrow-2);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-label);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* ---- Weight helpers (compose with any role class) ---- */.master-footer .fw-light { font-weight: var(--fw-light); }.master-footer .fw-regular { font-weight: var(--fw-regular); }.master-footer .fw-medium { font-weight: var(--fw-medium); }.master-footer .fw-semibold { font-weight: var(--fw-semibold); }.master-footer .fw-bold { font-weight: var(--fw-bold); }

/* ============================================================
   MOBILE-OPTIMISED SCALE  (≤760px — the site's mobile breakpoint)
   The desktop scale above is locked; this only retunes phones.
   Token-level overrides, so every .t-* role class inherits them.

   Readability principles applied:
   - Body copy never drops below 16px (Body Normal = 16, Body Large = 18);
     the 11px meta label is bumped to 12px so it stays legible on small screens.
   - Oversized desktop display/headings are stepped down to a phone scale
     (a ~1.18 ratio) so headlines don't eat the viewport or wrap awkwardly.
   - Line-height opens up: body → 1.55 (comfortable measure), and headings
     loosen from 1.04 → 1.14 so multi-line mobile headings aren't cramped.
   - Negative tracking is relaxed at small sizes (tight tracking hurts
     legibility on phones); eyebrow/all-caps tracking is kept.
   ============================================================ */
@media (max-width: 760px) {.master-footer {
    /* Display & headings — phone scale */
    --fs-display-1: 3.5rem;   /* 80 → 56px */
    --fs-display-2: 3rem;     /* 70 → 48px */
    --fs-h1: 2.5rem;          /* → 40px */
    --fs-h2: 2rem;            /* → 32px */
    --fs-h3: 1.75rem;         /* → 28px */
    --fs-h4: 1.5rem;          /* → 24px */
    --fs-h5: 1.375rem;        /* → 22px */
    --fs-h6: 1.25rem;         /* → 20px */

    /* Body & UI — kept at readable sizes (≥16px for copy); tiny label bumped */
    --fs-body-lg:   1.125rem; /* 18px */
    --fs-body:      1rem;     /* 16px */
    --fs-body-sm:   0.875rem; /* 14px */
    --fs-body-tiny: 0.75rem;  /* 11 → 12px (legibility) */
    --fs-eyebrow-1: 0.8125rem;/* 13px */
    --fs-eyebrow-2: 0.6875rem;/* 11px */

    /* Line heights — more open for small-screen reading */
    --lh-display: 1.06;
    --lh-tight:   1.14;
    --lh-snug:    1.24;
    --lh-normal:  1.55;
    --lh-label:   1.3;

    /* Letter spacing — relaxed at small sizes */
    --tracking-display: -0.025em;
    --tracking-heading: -0.02em;
    --tracking-snug:    -0.015em;
    --tracking-body:    -0.01em;
  }

}


/* ==== chrome.css ========================================================= */
.master-footer .contact__info { container-type: inline-size; }.master-footer .contact__title { font-size: max(56px, 11.9vw); }
@supports (container-type: inline-size) {.master-footer .contact__title { font-size: max(56px, 13.87cqw); }

}
.master-footer .contact__details {
  align-items: flex-start;
  gap: clamp(28px, 4vw, 64px);
}.master-footer .contact__reach {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.6vw, 44px);
}.master-footer .contact__socials { display: flex; align-items: center; gap: 10px; }.master-footer .contact__nav {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  gap: clamp(4px, 0.5vw, 9px);
}.master-footer .contact__nav-link {
  font-weight: var(--fw-medium);
  font-size: clamp(16px, 1.25vw, 20px);
  letter-spacing: -0.02em;
  line-height: 1.45;
  /* Same gradient underline the .link-arrow spans it replaces used, so the
     hover reads identically to the rest of the page. */
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1.5px;
  background-repeat: no-repeat;
  background-position: 100% 100%;
  transition: background-size 0.4s var(--ease-out);
}.master-footer .contact__nav-link:hover { background-size: 100% 1.5px; }.master-footer .social {
  --chip: clamp(28px, 2.4vw, 38px);
  display: inline-flex;
  width: var(--chip);
  height: var(--chip);
  /* currentColor paints the chip and the shapes knocked out of the glyph
     (see index.html) — one declaration for both. */
  color: var(--white-1);
  transition: transform 0.3s var(--ease-out);
}.master-footer .social__glyph { width: 100%; height: 100%; display: block; }.master-footer .social:hover { transform: translateY(-3px); }.master-footer .contact__email-text::after { transform: scaleX(1); }.master-footer .footer { align-items: baseline; }.master-footer .footer__name,
.master-footer .footer__legal {
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-normal);
  letter-spacing: var(--tracking-body);
  opacity: 0.85;
}
@media (max-width: 760px) {.master-footer .contact__details { flex-direction: column; gap: 30px; }.master-footer .contact__reach { flex-wrap: wrap; gap: 18px; }.master-footer .contact__nav {
    margin-left: 0;
    align-items: flex-start;
    text-align: left;
    gap: 8px;
  }.master-footer .contact__nav-link { background-position: 0 100%; }.master-footer .footer { align-items: flex-start; }

}


