/* ---- tokens.css ---- */
/* ============================================================================
   TOKENS — Larkin Inc.

   Every value here was measured off the live larkinco.ca at viewport 1440,
   not eyeballed. See .scrape/DESIGN-NOTES.md for the full audit and the
   measurement method.

   Type and spacing use clamp() so they scale smoothly between a small phone
   (~360px) and the 1140px container. No breakpoints, no jumps.
   Formula used throughout:  clamp(MIN, <intercept>rem + <slope>vw, MAX)
   ========================================================================= */

:root {
  /* ---- brand ----------------------------------------------------------
     #00902A is the accent measured off the original: 179 occurrences across
     the homepage, second only to body grey. It is the nav link colour and the
     green of the shamrock in the logo.

     It also FAILS WCAG AA at normal text sizes, in both directions:
       #00902A as text on white ............ 4.18:1  (needs 4.5:1)
       white text on a #00902A fill ........ 4.18:1  (needs 4.5:1)
     Larkin's nav links are 12px and their CTA buttons are 12px white-on-green,
     so both fail on the live site today.

     Until 2026-09-30 --green was #007322 (the original's own link-hover green,
     6.04:1) for that reason. On 2026-09-30 the operator ruled that the live
     site is the reference for what the staged site looks like, so --green is
     the exact original accent again and the small-text failures above are back
     on purpose. TO GET AA BACK, set --green to #007322 and --green-cnb to
     #007322: those two lines are the whole change. */
  --green: #00902A;
  --green-brand: #00902A;  /* same value; kept so older rules still resolve */
  --green-dark: #007322;   /* hover: the original's own link-hover green */
  --green-cnb: #009900;    /* floating call button, as on the original */

  /* ---- neutrals ------------------------------------------------------- */
  --ink: #212529;          /* headings, button fill, footer band */
  --ink-alt: #1C2023;      /* footer-bottom band */
  /* The original's body grey is #777777, which is 4.48:1 on white and 4.07:1
     on the grey band — both just under the AA threshold. #6E6E6E is visually
     almost identical and clears it at 5.10:1 and 4.64:1.
     The original's #999999 secondary grey is 2.85:1 on white, a clear failure;
     #767676 is the lightest grey that passes. */
  --body: #6E6E6E;         /* was #777777 on the original */
  --muted: #767676;        /* was #999999 on the original */
  /* The original sets the footer-bottom copyright line to #555555 on a #1C2023
     band — 2.20:1, effectively unreadable. #9a9a9a gives 5.83:1 and still
     reads as quiet secondary text. */
  --muted-dark: #9a9a9a;   /* was #555555 on the original */
  --dark-3: #333333;
  --white: #ffffff;
  --grey-band: #f4f4f4;    /* topbar */
  --grey-soft: #f7f7f7;
  --grey-hero: #f2f2f2;
  --line: #e8e8e8;

  /* ---- type -----------------------------------------------------------
     Open Sans carries everything structural. Shadows Into Light is the
     handwritten accent, used only on emphasis words ("Strategy", "Planning",
     "Build", "Our Work", "easily", "accesorize") at weight 400.
     Playfair Display and Abril Fatface are loaded by the old site but never
     applied to any rendered text — dropped. */
  --font: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-accent: "Shadows Into Light", "Open Sans", cursive;

  --fs-body: 0.875rem;                                          /* 14px measured */
  --fs-lead: 1rem;
  --fs-h1-hero: clamp(1.625rem, 1.32rem + 1.36vw, 2rem);        /* 26 → 32 (home h1) */
  --fs-h1: clamp(1.75rem, 1.34rem + 1.82vw, 2.25rem);           /* 28 → 36 (inner h1) */
  --fs-h2: clamp(1.5rem, 1.32rem + 0.82vw, 1.875rem);           /* 24 → 30 measured */
  --fs-h3: clamp(1.125rem, 1.02rem + 0.45vw, 1.375rem);         /* 18 → 22 */
  --fs-h4: clamp(1.0625rem, 0.99rem + 0.34vw, 1.25rem);         /* 17 → 20 measured */
  --fs-accent: clamp(1.375rem, 1.13rem + 1.09vw, 1.925rem);     /* 22 → 30.8 measured */
  --fs-accent-sm: clamp(1.25rem, 1.09rem + 0.7vw, 1.575rem);    /* 20 → 25.2 measured */
  --fs-sub: clamp(1.0625rem, 0.99rem + 0.34vw, 1.25rem);        /* 17 → 20 */
  --fs-tile-title: 1.0625rem;                                   /* 17px measured */
  --fs-nav: 0.75rem;                                            /* 12px measured */
  --fs-small: 0.8125rem;
  --fs-topbar: 0.6875rem;                                       /* 11px measured */
  --fs-footer: 0.7875rem;                                       /* 12.6px measured */
  --fs-footer-bottom: 0.70875rem;                               /* 11.34px measured */

  --lh-body: 1.714;        /* 24px at 14px — measured */
  --lh-heading: 1.33;      /* 40px at 30px — measured */

  /* Negative tracking on every heading is the signature of this type
     treatment: measured −1.8px at 36px, −1.5px at 30px, −1px at 20px.
     That is a consistent −0.05em. */
  --ls-heading: -0.05em;
  --ls-h1: -0.05em;        /* measured −1.8px at 36px */
  --ls-h2: -0.05em;        /* measured −1.5px at 30px */
  --ls-h3: -0.05em;        /* measured −1px at 20px */
  --ls-nav: -0.042em;      /* −0.5px at 12px */

  /* ---- spacing --------------------------------------------------------
     Content rows measure 60px top padding on the original. */
  --section-y: clamp(2.5rem, 1.77rem + 3.27vw, 3.75rem);        /* 40 → 60 */
  --section-y-tight: clamp(1.75rem, 1.35rem + 1.8vw, 2.5rem);   /* 28 → 40 */
  --gap: 30px;                                                  /* measured tile gutter */

  --container: 1140px;                                          /* measured */
  --gutter: 15px;                                               /* measured */

  /* ---- grid minimums --------------------------------------------------
     Tuned so the 1140px container (1110px inside padding) yields the column
     counts the original uses. The portfolio grid measured 4 × 255px tiles
     with 30px gutters: 4(255) + 3(30) = 1110. */
  --col-min-2: 420px;
  --col-min-3: 300px;
  --col-min-4: 255px;      /* measured tile width */
  --col-min-gallery: 290px;

  /* ---- chrome ---------------------------------------------------------
     Measured: grey strip 31px, header-main 131px, total 165px (3px top border
     included). The header IS sticky on the original (70px bar past ~90px of
     scroll) and on this rebuild since 2026-09-30; see header.css. */
  --topbar-h: 31px;
  --header-h: 131px;
  --logo-w: clamp(150px, 14vw, 200px);   /* original renders at 200x99 */

  /* Measured, not assumed: the original's buttons are NOT square.
     "What we do!" (dark) is 6px; the green "Ask about …" CTAs are 4px.
     Cards, tiles and images have no radius at all. */
  --radius: 4px;           /* green CTAs, form controls */
  --radius-btn-dark: 6px;  /* the dark primary button */
  --radius-fab: 50%;       /* the call button is a circle */

  /* The original has no card shadows and no hover elevation — the hover
     vocabulary is colour only. These stay minimal deliberately. */
  --shadow-card: none;
  --shadow-tile-overlay: 0 0 0 rgba(0, 0, 0, 0);

  --transition: 0.2s ease;
  --transition-slow: 0.6s ease;   /* matches the word-rotator's 0.6s ease */

  /* ---- the one structural breakpoint ---------------------------------
     Only where layout genuinely changes: the nav collapsing to a drawer.
     Media queries cannot read custom properties, so this documents the
     value and each query repeats it literally. */
  --bp-nav: 991px;
}

/* ---- base/fonts.css ---- */
/* Self-hosted fonts, from assets/fonts/ — no request leaves this origin.

   These are exactly the @font-face rules Google Fonts served on 2026-09-22 for
     css2?family=Open+Sans:wght@300;400;600;700&family=Shadows+Into+Light&display=swap
   (fetched with a desktop Chrome User-Agent, which is what gets woff2), with
   only the url() rewritten to a local file. Same families, weights, styles,
   unicode-range and font-display, so the browser picks the same faces.

   Open Sans is a variable font: each subset is ONE file, named in the four
   weight rules below it. A browser only downloads a subset whose
   unicode-range the page actually uses — measured on / and /about-us/, that
   is Open Sans's latin file, plus Shadows Into Light's latin file on a page
   that shows the accent. */

/* cyrillic-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* hebrew */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* math */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-math.woff2') format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* symbols */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-symbols.woff2') format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
/* vietnamese */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 300;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* hebrew */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* math */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-math.woff2') format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* symbols */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-symbols.woff2') format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
/* vietnamese */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* hebrew */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* math */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-math.woff2') format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* symbols */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-symbols.woff2') format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
/* vietnamese */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* hebrew */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* math */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-math.woff2') format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* symbols */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-symbols.woff2') format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
/* vietnamese */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* 800 — added 2026-09-30. Not one of the four weights above: the live site asks Google for
   300-800 and its `b` (900) and `.portfolio-desc strong` (800) draw at 800, which the
   same variable files hold. Only the two subsets this site's text uses. */
/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fonts/open-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Shadows Into Light';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/shadows-into-light-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Shadows Into Light';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/shadows-into-light-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- base/reset.css ---- */
/* ---- reset & document defaults ------------------------------------------ */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
/* Live, phones: the root drops to 92.86% (14.8576px), so everything set in rem
   follows - body type 14px -> 13px, a 20px paragraph gap -> 18.57px. */
@media (max-width: 575px) { html { font-size: 92.86%; } }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 24px;              /* live is a length, not a ratio: 20px on a phone */
  color: var(--body);
  background: var(--white);
  /* No font smoothing override: the live site leaves it at `auto`, which draws
     text a little heavier on a Mac than `antialiased` does (measured on the
     Strategy / Planning / Build captions, 2026-09-30). */
  overflow-x: hidden;
}
@media (max-width: 575px) { body { line-height: 20px; } }

img {
  max-width: 100%;
  height: auto;
  display: block;
  border: 0;
}

a {
  color: var(--green);
  text-decoration: none;
  transition: color var(--transition);
}
a:hover { color: var(--green-dark); }

p { margin: 0 0 1.25rem; }   /* live: 20px (18.57px on a phone) */
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1rem; padding-left: 1.25rem; }

/* Keyboard focus was invisible in the original theme. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}

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

.skip-link {
  position: absolute;
  top: -60px;
  left: 12px;
  z-index: 2000;
  padding: 10px 18px;
  background: var(--ink-alt);
  color: #fff;
  font-weight: 600;
  transition: top var(--transition);
}
.skip-link:focus { top: 12px; color: #fff; }

/* ---- base/typography.css ---- */
/* ---- typography ----------------------------------------------------------
   All sizes are fluid via clamp(), so there is not a single font-size media
   query anywhere in this stylesheet.

   The defining trait of this type treatment is negative tracking on every
   heading — measured −1.8px at 36px, −1.5px at 30px, −1px at 20px, a
   consistent −0.05em. Without it the headings read wider and softer than the
   original.
   -------------------------------------------------------------------------- */

/* Porto: <strong> is 700 and <b> is 900 (which a font with no 900 draws as its
   heaviest), whatever the weight around them — inside a light heading or lead
   the browser's `bolder` would otherwise give only 400. */
strong { font-weight: 700; }
b { font-weight: 900; }

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 1rem;
  color: var(--ink);
  font-weight: 600;
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
}

h1 { font-size: var(--fs-h1); font-weight: 400; }
h2 { font-size: var(--fs-h2); font-weight: 300; }
h3 { font-size: var(--fs-h3); font-weight: 600; }
h4 { font-size: var(--fs-h4); font-weight: 600; }

/* Porto's `.alternative-font`: the handwritten face in the brand green, 1.6em, for
   one word inside a line of type ("easily", "accesorize"). */
.alternative-font {
  color: var(--green);
  font-family: var(--font-accent);
  font-size: 1.6em;
  font-weight: 400;
  display: inline-block;           /* so the space inside the span, at the start of its box, drops out as on the live page */
  vertical-align: top;             /* and the big handwriting does not make the line taller (live: 28.8px line, word sits low) */
}

/* Porto's `.lead`, measured on larkinco.ca: 1.25em, light, tracked in 0.05em, a
   28.8px line (1.8rem, so 26.7px on a phone). */
.lead {
  font-size: 1.25em;
  font-weight: 300;
  line-height: 1.8rem;
  letter-spacing: -0.05em;
  color: var(--body);
}

/* A plain hairline rule. The original uses <hr class="separator-line"> between
   sections on several pages — 1px, full width, no decoration. */
.separator-line {
  height: 1px;
  margin: var(--section-y-tight) 0;
  border: 0;
  background: var(--line);
}

/* ---- base/layout.css ---- */
/* ---- layout primitives ---------------------------------------------------
   The grids here use auto-fit + minmax, so they reflow on their own at every
   width.

   The CONTAINER does not: it steps, exactly as the live site's does. Measured
   on larkinco.ca at 11 widths (2026-09-30), for header, footer and page content
   alike:
     below 576px ..... full width, 20px side padding
     576 - 991px ..... full width, 30px side padding
     992 - 1199px .... 960px wide, centred, 15px padding
     1200px and up ... 1140px wide, centred, 15px padding
   Before this, the container was one fluid 1140px box, so tablet and small
   laptop widths had different margins from the original on every page.
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  margin: 0 auto;
  padding: 0 20px;
}
@media (min-width: 576px) { .container { padding: 0 30px; } }
@media (min-width: 992px) { .container { max-width: 960px; padding: 0 var(--gutter); } }
@media (min-width: 1200px) { .container { max-width: var(--container); } }

.section { padding: var(--section-y) 0; position: relative; }

.row {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -15px;
}
.row > * { padding: 0 15px; }

/* min(…, 100%) stops a column from ever being wider than its container,
   which is what would otherwise cause horizontal scroll on small phones. */
.grid { display: grid; gap: var(--gap); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(var(--col-min-2), 100%), 1fr)); }

/* ---- base/grid.css ---- */
/* ---- 12-column grid ---------------------------------------------------------
   The live site is Bootstrap 5 under Porto: `.row` pulls 15px out each side,
   every child has 15px of its own, and `.col-{sm,md,lg,xl}-N` / `.offset-*` turn
   on at 576 / 768 / 992 / 1200px. Only the sizes the pages use are written here
   (generated 2026-09-30; add a size to the list and regenerate). */

.row { display: flex; flex-wrap: wrap; margin-left: -15px; margin-right: -15px; }
.row > * { flex-shrink: 0; width: 100%; max-width: 100%; padding-left: 15px; padding-right: 15px; position: relative; }
.row--center { align-items: center; }

@media (min-width: 576px) {
  .col-sm-8 { flex: 0 0 auto; width: 66.666667%; }
  .offset-sm-5 { margin-left: 41.666667%; }
}
@media (min-width: 768px) {
  .col-md-3 { flex: 0 0 auto; width: 25%; }
  .col-md-4 { flex: 0 0 auto; width: 33.333333%; }
  .col-md-5 { flex: 0 0 auto; width: 41.666667%; }
  .col-md-6 { flex: 0 0 auto; width: 50%; }
  .col-md-7 { flex: 0 0 auto; width: 58.333333%; }
  .col-md-9 { flex: 0 0 auto; width: 75%; }
  .col-md-12 { flex: 0 0 auto; width: 100%; }
  .offset-md-4 { margin-left: 33.333333%; }
  .mx-md-auto { margin-left: auto; margin-right: auto; }
}
@media (min-width: 992px) {
  .col-lg-1 { flex: 0 0 auto; width: 8.333333%; }
  .col-lg-2 { flex: 0 0 auto; width: 16.666667%; }
  .col-lg-3 { flex: 0 0 auto; width: 25%; }
  .col-lg-4 { flex: 0 0 auto; width: 33.333333%; }
  .col-lg-5 { flex: 0 0 auto; width: 41.666667%; }
  .col-lg-6 { flex: 0 0 auto; width: 50%; }
  .col-lg-7 { flex: 0 0 auto; width: 58.333333%; }
  .col-lg-8 { flex: 0 0 auto; width: 66.666667%; }
  .col-lg-9 { flex: 0 0 auto; width: 75%; }
  .col-lg-10 { flex: 0 0 auto; width: 83.333333%; }
  .col-lg-12 { flex: 0 0 auto; width: 100%; }
  .offset-lg-1 { margin-left: 8.333333%; }
  .offset-lg-2 { margin-left: 16.666667%; }
}
@media (min-width: 1200px) {
}

/* ---- components/button.css ---- */
/* ---- buttons & arrow links ----------------------------------------------
   Larkin's buttons are flat. The effects audit found no drawing pseudo-
   elements anywhere on the original and no hover rule that changes transform,
   shadow or opacity — the entire hover vocabulary on this site is colour.
   So there is no offset shadow here and no hover translate.

   Two measured variants, and they differ in more than colour:

   .btn--dark   "What we do!"        114x37, 14px/600, sentence case,
                                     #fff on #212529, padding 8px 14px, radius 6px
   .btn--green  "Ask about Versa"    159x43, 12px/600, UPPERCASE,
                                     #fff on #00902A, padding 12px 24px, radius 4px

   The uppercase and the smaller size on the green CTA are easy to miss and
   are what make it read as a call to action rather than a link.

   Minimum height is raised to 40px on both so every button clears the WCAG 2.2
   24x24 target minimum comfortably; the original's 37px dark button already
   did, and this keeps them consistent.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  border: 0;
  font-family: inherit;
  line-height: 1.4;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--transition), color var(--transition);
}

/* ---- Porto's primary / "modern" button, as the live site draws it -----------
   Green, 12px / 600, capitals, 12px x 24px inside, 4px corners (measured at
   1440: 159 x 43 for "Ask about Versa!"). Padding and type are in rem/em so a
   phone's smaller root scales them as the live one does. ------------------- */
.btn-green {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  border: 1px solid var(--green);
  border-radius: 4px;
  background: var(--green);
  color: #fff;
  font-family: inherit;
  font-size: 0.85714em;
  font-weight: 600;
  line-height: 1.4286;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.2s;
}
.btn-green:hover { background: var(--green-dark); }

/* the card button and the "Load more" button: the same small shape, 12.8px type,
   a 1px clear border (a 37.3px box), in red and in blue */
.btn-read,
.btn-load {
  display: inline-block;
  padding: 0.666em 1.1663em;
  border: 1px solid transparent;
  border-radius: 4px;
  color: #fff;
  font-family: inherit;
  font-size: 0.91429em;
  line-height: 1.4286;
  cursor: pointer;
  transition: background-color 0.2s;
}
.btn-read { background: #f4524d; }
.btn-read:hover { background: #e2403b; color: #fff; }
.btn-load { background: #5472d2; }
.btn-load:hover { background: #4361c1; color: #fff; }

/* ---- components/header.css ---- */
/* ---- header & navigation -------------------------------------------------
   Rebuilt 2026-09-30 to match the live site, value for value. Every number
   below was read off larkinco.ca at 1440 (and 390 for the phone header) with a
   real pointer, in each state: rest, hover, current page, dropdown open,
   scrolled. Structure (live class -> here):
     #header .header-top ............ .site-header .header-top   (empty 31px strip)
     .header-main .header-container . .header-main .header-container
     .header-left .logo ............. .header-left .logo
     .header-right-top .nav-top ..... .header-right-top .nav-top (address, phone)
     .searchform-popup .search-toggle  .header-search .search-toggle
     #main-menu .main-menu .sub-menu  #main-menu .main-menu .sub-menu
     a.mobile-toggle + nav#nav-panel . .mobile-toggle + .nav-panel (accordion)

   Earlier versions of this file said the original header does not stick. It does:
   `.header-main.sticky` goes position:fixed at scrollY > ~90 (desktop) / ~50
   (phone), 70px / 68px tall, logo halved, contact row gone. Reproduced below.

   The 991/992 boundary is the live site's own desktop-menu breakpoint.
   -------------------------------------------------------------------------- */

.site-header {
  position: relative;
  z-index: 1000;
  border-top: 3px solid #ededed;
  background: var(--white);
  font-size: 0.875rem;
}

/* The grey strip above the header row: 31px, #f4f4f4, a 1px #ededed line under it. */
.header-top {
  display: none;               /* live: only from 768px up */
  height: 31px;
  background: var(--grey-band);
  border-bottom: 1px solid #ededed;
}
@media (min-width: 768px) { .header-top { display: block; } }

.header-main { position: relative; background: var(--white); }

/* The live header is a table: two cells that share the row in proportion to
   their content (the logo gives way first, down to 80px). A flex row came out
   the same above 640px and wrongly kept the logo at 100px below it, where the
   live contact row wraps and the header grows. */
.header-container {
  display: table;
  width: 100%;
}

.header-left,
.header-right { display: table-cell; vertical-align: middle; padding: 16px 0; }
.logo { display: block; max-width: 200px; min-width: 80px; }
.logo img { display: block; width: 100%; height: auto; }

.header-right { text-align: right; }

/* ---- contact row ---------------------------------------------------------- */
.header-right-top {
  display: flex;
  flex-wrap: wrap;                /* narrow: the phone drops under the address, the search under both */
  align-items: center;
  justify-content: flex-end;
}
.nav-top {
  display: flex;
  flex-wrap: wrap;
  white-space: nowrap;
  text-align: left;
  margin: 0 10px 0 0;
  padding: 0;
  list-style: none;
  font-size: 12.6px;
}
.nav-top a {
  display: inline-flex;
  align-items: center;
  padding: 6px 10px 6px 0;
  color: var(--muted);
  border-radius: 4px;
  transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
.nav-top a:hover { color: var(--green); }
.nav-top svg { flex: none; margin-right: 6px; }
/* The phone's link is padded on both sides (10px, the live `span`), and a faint
   1px rule closes the item: 16px tall, 10px down from its top (live ::after). */
.nav-phone { position: relative; padding-right: 10px; margin-right: 0; }
.nav-phone a { padding-left: 10px; }
.nav-phone::after {
  content: "";
  position: absolute;
  top: 10px;
  right: 0;
  width: 1px;
  height: 16px;
  background: rgba(0, 0, 0, 0.05);
}

.header-search { position: relative; display: inline-block; }
.search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #444;                    /* live: rgb(68, 68, 68) */
  cursor: pointer;
  width: 16.8px;
  height: 24px;                   /* a line of the body's 24px (20px on a phone) */
  position: relative;
  top: 1px;                       /* live: the icon sits 1.2px below its 25.3px box */
}
.search-toggle:hover { color: var(--green); }

/* The search box drops down under the icon, as the live "simple search". */
.search-form {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 10;
  display: flex;
  width: 260px;
  margin-top: 10px;
  padding: 6px;
  background: var(--white);
  border: 1px solid #eee;
  border-top: 3px solid var(--green);
  border-radius: 0 0 4px 4px;
  box-shadow: 0 5px 8px rgba(0, 0, 0, 0.15);
}
.search-form[hidden] { display: none; }
.search-form input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 6px 10px;
  border: 1px solid #eee;
  border-right: 0;
  border-radius: 4px 0 0 4px;
  font: inherit;
  font-size: 13px;
  color: #555;
}
.search-form button {
  flex: none;
  width: 38px;
  border: 0;
  border-radius: 0 4px 4px 0;
  background: var(--green);
  color: #fff;
  cursor: pointer;
}
.search-form button:hover { background: var(--green-dark); }

/* ---- main menu ------------------------------------------------------------ */
.header-right-bottom {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin: 8px 0 6px;
}
#main-menu { margin-right: 14.8px; }
.main-menu {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}
.main-menu > li { position: relative; margin-right: 1px; }
.main-menu > li:last-child { margin-right: 0; }

.main-menu > li > a {
  display: inline-block;
  position: relative;
  padding: 10px 16px;
  border-radius: 4px;
  color: var(--green);
  font-size: 12px;
  font-weight: 700;
  line-height: 20px;
  letter-spacing: -0.5px;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
/* Hover and the current page are the same solid green pill, white text. With a
   dropdown open the pill's bottom corners square off to meet it. */
/* Live: the menu's side padding is 14px from 992 to 1199px, 16px from 1200px. */
@media (min-width: 992px) and (max-width: 1199px) {
  .main-menu > li > a { padding-left: 14px; padding-right: 14px; line-height: 18px; }
}
.main-menu > li:hover > a,
.main-menu > li:focus-within > a,
.main-menu > li.is-active > a {
  background: var(--green);
  color: #fff;
  z-index: 1;
}
.main-menu > li.has-sub:hover > a,
.main-menu > li.has-sub:focus-within > a { border-radius: 4px 4px 0 0; }

.main-menu .sub-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 10;
  min-width: 200px;
  margin: 0;
  padding: 5px 0;
  list-style: none;
  background: var(--white);
  border-top: 3px solid var(--green);
  border-radius: 0 4px 4px 4px;
  box-shadow: 0 5px 8px rgba(0, 0, 0, 0.15);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease-in-out, visibility 0.2s;
}
.main-menu > li:hover > .sub-menu,
.main-menu > li:focus-within > .sub-menu { opacity: 1; visibility: visible; }
.main-menu > li.flip > .sub-menu,
html:not(.js) .main-menu > li.has-sub:last-child > .sub-menu { left: auto; right: 0; }   /* see flipSubmenus() in 20-nav.js */

.main-menu .sub-menu a {
  display: block;
  position: relative;
  padding: 8px 18px;
  border-bottom: 1px solid #f3f3f3;
  color: #777;
  font-size: 12.8px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: -0.5px;
  white-space: nowrap;
  transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
.main-menu .sub-menu a:hover,
.main-menu .sub-menu a[aria-current="page"] { background: #f4f4f4; }

/* ---- sticky ---------------------------------------------------------------
   Live: `.header-main.sticky.change-logo` — fixed at the top, white, a faint
   shadow, a 3px #ededed top edge, z-index 1001, 70px tall. The logo halves
   (200 -> 100px), the padding halves (16 -> 8px), the contact row goes. There
   is no transition on the live site, so there is none here either. JS adds the
   class and gives #header its old height so the page does not jump. */
.header-main.is-sticky {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1001;
  border-top: 3px solid #ededed;
  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.06);
}
.is-sticky .header-left,
.is-sticky .header-right { padding-top: 8px; padding-bottom: 8px; }
.is-sticky .logo { max-width: 100px; }
.is-sticky .header-right-top { display: none; }
.is-sticky .header-right-bottom { margin: 5px 0 6px; }
/* The sticky logo is a smaller picture: live swaps in `sticky-logo`, 80px wide,
   centred in the same 100 x 49.3 box. The row is then 67px on desktop (70px with
   the border) because the menu keeps 5px above and 6px below it. */
.is-sticky .logo { display: flex; align-items: center; height: 49.33px; }
.is-sticky .logo img { width: 80px; }

/* ---- phone / tablet -------------------------------------------------------- */
.mobile-toggle { display: none; }
.nav-panel[hidden] { display: none; }

@media (max-width: 991px) {
  .logo { max-width: 100px; }
  .main-menu { display: none; }
  #main-menu { margin: 0; }
  .header-right-bottom { margin: 0; min-height: 50px; }

  /* the green square button: 37 x 34, #00902A, 4px corners */
  .mobile-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 8px 0 8px 10.4px;
    padding: 7px 13px;
    border: 0;
    border-radius: 4px;
    background: var(--green);
    color: #fff;
    cursor: pointer;
    height: 34px;
    line-height: 20px;
    transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out;
  }
  .mobile-toggle svg { width: 11.375px; height: 13px; }
  .mobile-toggle:hover { background: var(--green-dark); }

  .is-sticky .header-left,
  .is-sticky .header-right { padding-top: 8px; padding-bottom: 8px; }
  .is-sticky .header-right-top { display: none; }
  .is-sticky .header-right-bottom { min-height: 0; margin: 5px 0 0; }
  .is-sticky .mobile-toggle { margin-top: 0; margin-bottom: 0; }

  /* Open menu: in flow under the header, or under the fixed bar when it sticks. */
  .nav-panel { padding: 0 0 15px; background: var(--white); }
  .nav-panel .container { padding: 0 20px; }
  .is-menu-sticky .nav-panel {
    position: fixed;
    top: 68px;
    left: 0;
    right: 0;
    z-index: 1001;
    max-height: calc(100vh - 68px);
    overflow-y: auto;
    box-shadow: 0 6px 8px rgba(0, 0, 0, 0.12);
  }

  .mobile-menu { margin: 0; padding: 0; list-style: none; }
  .mobile-menu li {
    position: relative;
    padding: 1px 0;
    border-bottom: 1px solid #e8e8e8;
  }
  .mobile-menu a {
    display: block;
    padding: 5px 6px;
    border-radius: 4px;
    color: #333;
    font-size: 11.7px;
    font-weight: 700;
    line-height: 25px;
    text-transform: uppercase;
    transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out;
  }
  .mobile-menu li.has-sub > a { padding-right: 33px; }
  .mobile-menu a:hover,
  .mobile-menu li.is-active > a { color: var(--green); }

  .nav-sub-toggle {
    position: absolute;
    top: 1px;
    right: 5px;
    z-index: 10;
    width: 30px;
    height: 35px;
    padding: 0;
    border: 0;
    border-radius: 3px;
    background: transparent;
    color: #333;
    cursor: pointer;
    transition: transform 0.25s;
  }
  .nav-sub-toggle:hover { color: var(--green); }
  .has-sub.open > .nav-sub-toggle { transform: rotate(180deg); }

  .mobile-sub { margin: 0 0 0 20px; padding: 0; list-style: none; }
  .mobile-sub[hidden] { display: none; }
  .mobile-sub li:last-child { border-bottom: 0; }
  .mobile-sub a { text-transform: none; }
}

/* Smallest phones (live): no address, a 32px contact row, 11.7px type. */
@media (max-width: 575px) {
  .header-left,
  .header-right { padding-top: 14.86px; padding-bottom: 14.86px; }    /* 16px x 13/14: the phone's 13px base type */
  .nav-address { display: none; }
  .search-toggle { height: 20px; }
  .nav-top { font-size: 11.7px; }
}

@media (prefers-reduced-motion: reduce) {
  .main-menu .sub-menu,
  .nav-sub-toggle { transition: none; }
}

/* ---- components/hero.css ---- */
/* ---- hero ----------------------------------------------------------------
   Larkin's homepage opens with a headline carrying an animated word rotator,
   a short lead line, one dark button, and the Made-in-Canada badge. There is
   no portrait, no colour band and no background image — the hero sits on
   white like the rest of the page.

   Measured: home h1 is 32px/44px weight 400 with −1.6px tracking (−0.05em),
   not uppercase. The "What we do!" button renders 114x37.
   -------------------------------------------------------------------------- */

/* ---- word rotator --------------------------------------------------------
   Porto's `word-rotator slide`, copied from the live stylesheet. A heading
   carries `.word-rotator`; inside it a prefix, the box of rotating words, and
   an optional suffix. The box clips its words; the one showing is in flow and
   the rest wait out of flow, so the box is as wide as the word showing (script
   sets that width, 35-rotator.js). The new word slides in from above and the
   old one drops out below, 0.6s ease. A pill (`.has-bg`) is a coloured box
   around the words; without it they are plain coloured text.

   The markup degrades cleanly: with JS off, the first word stays visible and
   the sentence still reads. */
.word-rotator .word-rotate-prefix,
.word-rotator .word-rotate-suffix,
.word-rotator-items {
  display: inline-block;
  vertical-align: middle;
  padding: 0.2em 0;
  font-weight: 700;
}
.word-rotator .word-rotate-prefix { margin-right: 0.375rem; }
.word-rotator .word-rotate-suffix { margin-left: 0.375rem; }

.word-rotator-items {
  position: relative;
  display: inline-flex;
  overflow: hidden;
  text-align: left;
  transition: width 0.4s ease-in-out;
}
.word-rotator-items b {
  display: inline-block;
  position: absolute;           /* no top/left: the static position, one 0.2em below the box edge */
  opacity: 0;
  font-style: normal;
  font-weight: inherit;
  white-space: nowrap;
}
.word-rotator-items b.is-active { position: relative; opacity: 1; }
.word-rotator-items b.is-in  { animation: slide-in 0.6s ease; }
.word-rotator-items b.is-out { animation: slide-out 0.6s ease; }

.word-rotator-items.has-bg { background: #0f8e27; color: #fff; }
.word-rotator-items.has-bg b { padding: 0.1rem 0.5rem; }

@keyframes slide-in {
  0%   { opacity: 0; transform: translateY(-100%); }
  60%  { opacity: 1; transform: translateY(20%); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes slide-out {
  0%   { opacity: 1; transform: translateY(0); }
  60%  { opacity: 0; transform: translateY(120%); }
  100% { opacity: 0; transform: translateY(100%); }
}

/* A missed animation is always better than unreadable text. */
@media (prefers-reduced-motion: reduce) {
  .word-rotator-items { transition: none; }
  .word-rotator-items b.is-in,
  .word-rotator-items b.is-out { animation: none; }
}

/* ---- components/team.css ---- */
/* ---- team cards (Porto "thumb-info") --------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca. A square photo; over its lower part a
   dark name plate with a green role tag; a green magnifier appears at the
   corner on hover and the photo grows 10% inside its frame. Below it, a green
   round button per way to reach the person.

   Measured at 1440: the grid is 940px (the middle 8 of 12 columns of a
   full-width row, less 20px) from 768px; below that it is the page's content
   width plus 30px (660px at 700, 380px at 390). 3 across from 992px, 2 from
   576px, 1 below;
   each card has 15px at the sides, a 283.3px photo, and 30px under it.
   The name plate runs from 66% to 87% of the photo's height. The plate is the
   card's one link (the live card links the photo, the plate and the zoom
   separately); its ::after stretches over the photo. */

.team-grid {
  display: grid;
  grid-template-columns: 1fr;
  width: calc(100% - 10px);
  margin: 0 auto 35px;
}
@media (min-width: 576px) { .team-grid { grid-template-columns: repeat(2, 1fr); width: calc(100% - 30px); } }
@media (min-width: 768px) { .team-grid { width: calc(66.6667% - 20px); } }
@media (min-width: 992px) { .team-grid { grid-template-columns: repeat(3, 1fr); } }

.member { padding: 0 15px 1px; margin: 0 0 30px; }

.thumb-info { position: relative; }
.thumb-info-wrapper { position: relative; overflow: hidden; }
.thumb-info-wrapper img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 3px;
  transition: 0.3s;
}
.thumb-info-wrapper:hover img { transform: scale(1.1); }

.thumb-info-title {
  position: absolute;
  left: 0;
  bottom: 13%;
  display: block;
  padding: 13px 21px 2px;
  background: rgba(33, 37, 41, 0.8);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.05em;
  transition: 0.3s;
}
.thumb-info-wrapper:hover .thumb-info-title { background: #000; }
/* the plate's link covers the whole photo, so the photo is a target too */
.member-link { color: inherit; text-decoration: none; }
.member-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.member-link:focus-visible { outline: none; }
.member-link:focus-visible::after { outline: 2px solid #fff; outline-offset: -4px; }
.thumb-info-inner { display: block; }
.thumb-info-type {
  display: block;
  width: fit-content;
  margin: 8px -2px -15px 0;
  padding: 2px 12px;
  border-radius: 2px;
  background: var(--green);
  color: #fff;
  font-size: 0.6em;
  font-weight: 600;
  line-height: 23.4px;
  letter-spacing: 0;
  text-transform: uppercase;
}
@media (min-width: 992px) { .thumb-info-title { font-size: 17px; } }

.zoom {
  position: absolute;
  right: 4px;
  bottom: 4px;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 100%;
  background: var(--green);
  color: #fff;
  opacity: 0;
  transition: 0.1s;
}
.thumb-info-wrapper:hover .zoom,
.zoom:focus-visible { opacity: 1; }

.thumb-info-caption { padding: 10px 0; }
.thumb-info-caption-text { min-height: 30px; }
.thumb-info-social-icons { display: block; }
.thumb-info-social-icons a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin: 2px;
  border-radius: 25px;
  background: var(--green);
  color: #fff;
  transition: 0.25s;
}
.thumb-info-social-icons a:hover { background: var(--green-dark); color: #fff; }

/* On /meet-our-team/ the grid fills the container (380px cards at 1440) instead of
   the middle two thirds of the page. */
.mt-team .team-grid { width: auto; margin: 0 -15px 35px; }
.mt-team { padding-top: 40px; }

/* ---- components/gallery.css ---- */
/* ---- filterable gallery + lightbox --------------------------------------- */

/* ---- lightbox ----------------------------------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: clamp(1.25rem, 0.5rem + 3vw, 2.5rem) 1.25rem;
  background: rgba(17, 19, 22, 0.94);
}
.lightbox.is-open { display: flex; }
.lightbox img {
  max-width: min(1100px, 92vw);
  max-height: 84vh;
  width: auto;
  object-fit: contain;
}
.lightbox__cap {
  position: absolute;
  bottom: 26px; left: 0; right: 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.86);
  font-size: var(--fs-body);
}
.lightbox__btn {
  position: absolute;
  width: 48px; height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  cursor: pointer;
  transition: background var(--transition);
}
.lightbox__btn:hover { background: var(--green); }
.lightbox__close { top: 22px; right: 22px; }
.lightbox__prev { left: 22px; top: 50%; transform: translateY(-50%); }
.lightbox__next { right: 22px; top: 50%; transform: translateY(-50%); }

/* ---- components/form.css ---- */
/* ---- the contact form and the contact page ----------------------------------
   Rebuilt 2026-09-30 from larkinco.ca's Contact Form 7 form, measured at 1440:
   bold 14px labels straight above 37px inputs with a hairline border, two to a
   row from 992px, a green "SEND MESSAGE" button. The inputs read 13.6px there
   (iOS Safari zooms the page when a field under 16px is focused, so on phones
   they are 16px here — the one place this form is not the live one). */

.form-title {
  margin: 0 0 8px;
  font-size: 30px;
  font-weight: 300;
  line-height: 40px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
.form-title b { font-weight: 900; }
.form-lede { margin: 0 0 3rem; }

.form-row { margin-left: -5px; margin-right: -5px; }      /* live: the columns sit 10px apart */
.form-row > * { padding-left: 5px; padding-right: 5px; }
.field { margin-bottom: 1rem; }
.field label {
  display: inline-block;
  color: #222529;
  font-weight: 700;
}
.field input,
.field textarea,
.field select {
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 3px;
  background: var(--white);
  font-family: inherit;
  font-size: 0.97143em;
  line-height: 1.4286;
  color: #777;
  transition: border-color var(--transition);
}
@media (max-width: 767px) { .field input, .field textarea, .field select { font-size: 16px; line-height: 1.2143rem; } }   /* same box as the 13.6px field */
.field input:focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--green);
  outline: none;
}
.field textarea { border-radius: 4px; resize: vertical; }

.form-status {
  margin-top: 16px;
  padding: 12px 16px;
  font-size: var(--fs-body);
  display: none;
}
.form-status.is-ok { display: block; background: #e8f5ec; color: #1c6b3a; }
.form-status.is-err { display: block; background: #fdecea; color: #a32218; }

/* The honeypot's wrapper. A CLASS and never a style attribute: this template
   ships 'unsafe-inline' in style-src, but several sites built from it have
   since tightened that to a bare `style-src 'self'`, where an inline style is
   dropped by the browser and the field it was hiding becomes a visible
   "Company" box on every contact page. A class works under both.
   Positioned off-canvas rather than `display:none` — some bots skip what is
   displayed none, and the whole point is that they fill it. */
.form-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Turnstile renders its own iframe into this div, so the box is not ours to
   style. The widget here is `interaction-only`, so it takes no room unless
   Cloudflare asks the visitor to do something; then it appears (300x65) and
   pushes the button down once, which is the price of having it invisible. */
.cf-turnstile { margin: 0; }

/* ---- components/footer.css ---- */
/* ---- footer, floating call button, back-to-top --------------------------
   Rebuilt 2026-09-30 to match the live footer, measured at 1440 and 390:
   `#footer` is #212529 and holds one `.footer-bottom` strip (#1C2023, 22px
   padding, 144px tall) with the AdLiBb bulb (80 x 80, 25px gap) beside the
   copyright line (11.34px). An earlier version added a "get in touch" band,
   the address, phone and hours; none of that is on the live site.

   One deliberate exception to "match the live values": the copyright colour.
   The live #555555 on #1C2023 is 2.20:1; --muted-dark (#9a9a9a) is 5.83:1 and
   is still a quiet grey.
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--ink);
  color: #777;
  font-size: 12.6px;
  line-height: 24px;
}

.footer-bottom {
  padding: 22px 0;
  background: var(--ink-alt);
  font-size: 11.34px;
  line-height: 24px;
  color: var(--muted-dark);
}

.footer-container { display: flex; align-items: center; }

.footer-left {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  padding: 10px 8px 10px 0;
  text-align: left;
}
.footer-left .logo {
  display: inline-block;
  flex: none;
  width: 80px;
  height: 80px;
  margin: 0 28px 0 0;        /* live: 25px margin + the 3px a space adds between inline blocks */
}
.footer-left .logo a { display: block; }
.footer-left .logo img { display: block; width: 80px; height: 80px; }

.footer-right {
  flex: 1 1 0;
  padding: 10px 0 10px 8px;
  text-align: right;
}

.footer-copyright { color: var(--muted-dark); }

/* Until 2026-09-30 /privacy-policy/ was linked from nowhere but the orphaned
   /site-map/, on a site whose contact form collects names and emails. */
.footer-legal {
  display: inline-flex;
  align-items: center;
  min-height: 28px;            /* WCAG 2.2 target size */
  color: inherit;              /* --muted-dark on --ink-alt: 5.83:1 */
  text-decoration: underline;
}
.footer-legal:hover { color: #fff; }   /* 16.4:1 */

/* Live: the two footer halves sit side by side from 992px up and stack below it. */
@media (max-width: 991px) {
  .footer-container { display: block; position: relative; }
  .footer-left { display: block; padding: 10px 0; }
  .footer-left .logo { display: block; width: auto; margin: 0 0 15px; }
  /* The live footer keeps an empty 25px block here. The privacy link is not on
     the live footer, so it sits at the right of the logo's row and leaves that
     block's height alone. */
  .footer-right { height: 25px; padding: 0; }
  .footer-legal { position: absolute; top: 10px; right: 0; }
}
/* the type steps down only on phones (live: 11.34px -> 10.53px, 24px -> 20px lines) */
@media (max-width: 575px) {
  .site-footer { font-size: 11.7px; line-height: 20px; }
  .footer-bottom { font-size: 10.53px; line-height: 20px; }
}

/* ---- floating controls --------------------------------------------------
   Call button: measured `a#callnowbutton`, tel: link, 55 x 55 circle, #009900,
   fixed right 20 / bottom 15, with a "Call Now!" label to its left (13px bold,
   #ececec on rgba(70,70,70,.9), 2px corners) — phones and tablets only.
   Back-to-top: measured 49x48, rgba(64,64,64,0.75), radius 4px 4px 0 0,
   bottom 0 right 10, fades in on scroll; desktop only. */
.call-fab {
  position: fixed;
  right: 20px;
  bottom: 15px;
  z-index: 1200;
  display: none;
  align-items: center;
  justify-content: center;
  width: 55px; height: 55px;
  border-radius: var(--radius-fab);
  background: var(--green-cnb);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
}
.call-fab:hover { background: var(--green-dark); color: #fff; }
.call-fab__label {
  position: absolute;
  right: calc(100% + 13px);
  top: 50%;
  transform: translateY(-50%);
  padding: 6px 8px;
  border-radius: 2px;
  background: rgba(70, 70, 70, 0.9);
  color: #ececec;
  font: 700 13px/13px Helvetica, Arial, sans-serif;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}

.to-top {
  position: fixed;
  right: 10px;
  bottom: 0;
  z-index: 900;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 49px; height: 48px;
  padding: 0;
  border: 0;
  border-radius: 4px 4px 0 0;
  background: rgba(64, 64, 64, 0.75);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0.25s, background var(--transition);
}
.to-top.is-visible { opacity: 1; visibility: visible; }
.to-top:hover { background: var(--green); }

/* Live switch points, bisected on larkinco.ca: the call button shows at 650px
   and below (the Call Now Button plugin's "mobile only"); the back-to-top
   button shows from 768px up. They overlap nowhere, and neither shows between
   651 and 767px. */
@media (max-width: 650px) { .call-fab { display: inline-flex; } }
@media (max-width: 767px) { .to-top { display: none; } }

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

/* ---- components/appear.css ---- */
/* ---- scroll-triggered entrance animations ---------------------------------
   The live site's "appear" system (Porto's appear-animate, measured
   2026-09-30): an element with data-appear-animation starts at opacity 0 and,
   when it scrolls into view, gets `animated <name>` — 1s, fill-mode both,
   after an optional data-appear-animation-delay in ms.

   Names used on the pages we keep, with the live keyframes copied exactly:
     fadeInUp ........ rises 30px            home h1, services, about
     fadeIn .......... opacity only          services, portfolio, about
     fadeInLeft/Right  slide 40px sideways   services, about, case studies
     zoomIn .......... scale .3 -> 1          about
     bounceIn ........ scale .3 -> 1.05 -> .9 -> 1   home Strategy/Planning/Build
     maskUp .......... a line slides up from behind a mask   headings

   Here: data-appear="<name>" and data-appear-delay="<ms>". 52-appear.js adds
   `.is-in`. Everything is gated on `.js`, so with JavaScript off nothing is
   ever hidden; prefers-reduced-motion shows everything at once. */

@keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } }
@keyframes zoomIn { 0% { opacity: 0; transform: scale(0.3); } 50% { opacity: 1; } 100% { opacity: 1; transform: scale(1); } }
@keyframes fadeInUp { 0% { opacity: 0; transform: translateY(30px); } 100% { opacity: 1; transform: translateY(0); } }
@keyframes fadeInLeft { 0% { opacity: 0; transform: translateX(-40px); } 100% { opacity: 1; transform: translateX(0); } }
@keyframes fadeInRight { 0% { opacity: 0; transform: translateX(40px); } 100% { opacity: 1; transform: translateX(0); } }
@keyframes bounceIn {
  0% { opacity: 0; transform: scale(0.3); }
  50% { opacity: 1; transform: scale(1.05); }
  70% { transform: scale(0.9); }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes maskUp { 0% { transform: translate(0, 100%); } 100% { transform: translate(0, 0); } }

.js [data-appear] { opacity: 0; }
.js [data-appear].is-in {
  opacity: 1;
  animation-duration: 1s;
  animation-fill-mode: both;
  animation-delay: var(--appear-delay, 0ms);
}
.js [data-appear="fadeIn"].is-in { animation-name: fadeIn; }
.js [data-appear="zoomIn"].is-in { animation-name: zoomIn; }
.js [data-appear="fadeInUp"].is-in { animation-name: fadeInUp; }
.js [data-appear="fadeInLeft"].is-in { animation-name: fadeInLeft; }
.js [data-appear="fadeInRight"].is-in { animation-name: fadeInRight; }
.js [data-appear="bounceIn"].is-in { animation-name: bounceIn; }
.js [data-appear="maskUp"].is-in { animation-name: maskUp; }

@media (prefers-reduced-motion: reduce) {
  .js [data-appear] { opacity: 1; }
  .js [data-appear].is-in { animation: none; }
  
}

/* letter-by-letter titles (57-portfolio.js): each .letter fades in, 1s, after its own delay */
.js [data-letters] .letter { opacity: 0; }
.js [data-letters].is-in .letter { opacity: 1; animation: fadeIn 1s both; animation-delay: var(--appear-delay, 0ms); }
@media (prefers-reduced-motion: reduce) { .js [data-letters] .letter { opacity: 1; animation: none !important; } }

/* ---- components/home.css ---- */
/* ---- homepage --------------------------------------------------------------
   Rebuilt 2026-09-30 to match the live homepage row for row. The live page is
   seven WPBakery rows; every number here was measured on larkinco.ca at 1440,
   1024, 768 and 390 (element rects and the page's own CSS rules):

     1. .home-mark      the 60-years badge, centred, half the viewport wide
     2. .home-intro     tagline (3 lines) + the dark "What we do!" button
     3. .home-claim     Made in Canada stamp + the fade-in rotating-word headline
     4. .concept        Strategy / Planning / Build circles + the "Our Work" flip card
     5. .home-clients   second rotating-word headline, the 300+ line, the logo carousel
     6. .home-mark      the big Larkin 60-years wordmark

   Vertical rhythm, all widths: wpb_content_element margin-bottom 35px; the rows
   after the intro start 60px lower; a constant 178px gap sits above the clients
   headline. */

/* ---- 1 & 6. centred marks -------------------------------------------------- */
.home-mark { margin-bottom: 35px; text-align: center; }
.home-mark img {
  display: block;
  width: calc(50% - 45px);        /* live: half of a full-bleed row, less 2 x 15px gutter and 15px */
  height: auto;
  margin: 0 auto;
}
/* below 768 the picture fills the container: its 30px side padding, 20px on a phone */
@media (max-width: 767px) { .home-mark img { width: calc(100% - 60px); } }
@media (max-width: 575px) { .home-mark img { width: calc(100% - 40px); } }

/* ---- 2. intro band ---------------------------------------------------------- */
.home-intro { color: var(--body); }
.home-intro__row { display: flex; flex-wrap: wrap; margin: 0 -15px; }
.home-intro__text { flex: 0 0 auto; width: 100%; padding: 0 15px; }
.home-intro__cta  { flex: 0 0 auto; width: 100%; padding: 0 15px; }
@media (min-width: 768px) {
  .home-intro__text { width: 66.6667%; }
  .home-intro__cta  { width: 33.3333%; }
}
.home-intro__text p { margin: 0 0 1.25rem; text-align: left; }
.home-intro__text p:last-child { margin-bottom: 0; }
.home-intro__text strong { font-weight: 700; }
.home-intro__text .is-soft { opacity: 0.7; }
.home-intro__cta { padding-top: 32px; padding-bottom: 32px; }

/* the dark button, measured: 114 x 37 at 14px type, 106 x 34 at 13px (its
   padding and type are in rem, so it follows the root), 600 weight, 6px corners */
.btn--intro {
  display: inline-block;
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--ink);
  border-bottom-color: #0a0b0d;
  border-radius: 6px;
  background: var(--ink);
  color: #fff;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.3333;
  text-align: center;
  cursor: pointer;
  transition: color 0.15s, background-color 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.2s;
}
.btn--intro:hover { background: #31373d; border-color: #383f46; color: #fff; }

/* ---- 3. stamp + headline ----------------------------------------------------- */
.home-claim { padding-top: 60px; }
.home-claim__inner { margin: 0 auto; }
@media (min-width: 768px) { .home-claim__inner { width: 83.3333%; } }
.home-claim__stamp {
  display: block;
  width: 200px;
  max-width: 100%;
  height: auto;
  margin: 0 auto 35px;
}

/* The headline: 32px on 44px lines, -0.05em, centred (the live h1's inline
   style). The heading itself is weight 400; only the words either side of the
   pill are bold, as on the live page. */
.home-claim h1,
.home-clients h2 {
  display: block;
  overflow: visible;
  margin: 0 0 15px;
  color: var(--ink);
  font-size: 32px;
  font-weight: 400;
  line-height: 44px;              /* 36.667px on a phone */
  letter-spacing: -0.05em;
  text-align: center;
}
@media (max-width: 575px) {
  .home-claim h1,
  .home-clients h2 { line-height: 36.6667px; }
}
.home-clients h2 { margin-bottom: 1rem; }

/* ---- 4. the concept diagram --------------------------------------------------
   Live `.porto-concept`: the dotted path, pins and arc are one background image
   (concept.png, centred, drawn above 992px only); a sun and a cloud are two
   halves of concept-icons.png; each circle sits on a frame from concept-item.png
   and the big "Our Work" frame is the right half of the same sprite. Three
   circle columns and one work column on a 12-column grid above 992px, stacked
   below it. */
.concept {
  position: relative;
  margin-bottom: 35px;
  padding-top: 60px;              /* live: p-t-xxl */
  background: url("/assets/img/concept.png") center 60px no-repeat;
}
.concept__inner { position: relative; }
@media (max-width: 991px) { .concept { background: none; } }

.concept__row {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  margin: 0 -15px;
  text-align: center;
}
.concept__col { flex: 0 0 auto; width: 100%; padding: 0 15px; }
@media (min-width: 992px) {
  .concept__col--step { width: 16.6667%; }
  .concept__col--first { margin-left: 8.33333%; }
  .concept__col--work { width: 33.3333%; margin-left: 8.33333%; }
}

.concept .sun,
.concept .cloud {
  position: absolute;
  display: block;
  height: 56px;
  background: url("/assets/img/concept-icons.png") 0 0 no-repeat;
}
.concept .sun { left: 0; top: 65px; width: 60px; }
.concept .cloud {
  left: 53%;
  top: 35px;
  width: 116px;
  background-position: 100% 0;
  animation: cloud-bob 3s ease-in-out infinite alternate;
}
/* Live: a script moves the cloud's `top` between 35px and about 55px, 3 seconds
   each way, easing at both ends (sampled every 0.7s). */
@keyframes cloud-bob { from { transform: translateY(0); } to { transform: translateY(20px); } }
@media (prefers-reduced-motion: reduce) { .concept .cloud { animation: none; } }

.process-image {
  display: flow-root;             /* keeps the picture's 8px margin inside the frame */
  position: relative;
  z-index: 1;
  width: 160px;
  height: 175px;
  margin: 120px auto 0;
  padding-bottom: 50px;
  background: url("/assets/img/concept-item.png") 0 0 no-repeat;
}
.process-image--mid { margin-top: 95px; }
@media (max-width: 991px) { .process-image { margin-top: 60px; } .process-image--mid { margin-top: 95px; } }
.process-image img {
  display: block;
  width: 144px;
  height: 144px;
  margin: 8px 8px 0;
  border-radius: 150px;
}
.concept strong {
  display: block;
  position: relative;
  margin-top: 38px;                /* 8px under the picture + 30px, as measured */
  color: var(--green);
  font-family: var(--font-accent);
  font-size: 1.8em;
  font-weight: 400;
}

.project-image {
  position: relative;
  z-index: 1;
  width: 350px;
  height: 420px;
  margin: 15px 0 0 -30px;
  padding-bottom: 45px;
  background: url("/assets/img/concept-item.png") 100% 0 no-repeat;
}
@media (max-width: 991px) { .project-image { margin: 60px auto 0; } }
@media (max-width: 575px) {
  .project-image { max-width: 160px; max-height: 250px; margin-left: auto; background-position: 0 0; }
}
.concept .our-work { margin-top: 52px; font-size: 2.2em; }

/* ---- the flip card ------------------------------------------------------------ */
.fc-slideshow {
  position: relative;
  top: 6px;
  width: 338px;
  height: 338px;
  margin: 0 6px;
  border-radius: 50%;
  perspective: 1200px;
}
@media (max-width: 575px) { .fc-slideshow { width: 145px; height: 145px; margin: 0 7.5px; } }
.fc-slides { margin: 0; padding: 0; list-style: none; }
.fc-slides img { display: block; width: 100%; height: auto; border-radius: 50%; }
.fc-slideshow:not(.is-live) li:not(:first-child) { display: none; }
.fc-slideshow.is-live .fc-slides { display: none; }

.fc-flip { position: absolute; inset: 0; border-radius: 50%; transform-style: preserve-3d; }
.fc-front,
.fc-back {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  backface-visibility: hidden;
  transform-style: preserve-3d;
}
.fc-back { transform: rotateY(180deg); }   /* script sets the turn's own axis while it runs */
.fc-front > div:first-child,
.fc-back > div:first-child { width: 100%; height: 100%; border-radius: 50%; overflow: hidden; }
.fc-front img,
.fc-back img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
/* the shading veils (live: white over the photo turning away, black over the one
   turning in), faded by script over 538ms */
.fc-overlay-light,
.fc-overlay-dark { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; }
.fc-overlay-light { background: #fff; opacity: 0; }
.fc-overlay-dark { background: #000; opacity: 1; }

/* arrows: the card is split into a left and a right half, each in three zones;
   hovering a zone shows the arrow, tilted up, level or down (live: ±45deg). */
.fc-nav { position: absolute; inset: 0; z-index: 10; display: flex; }
.fc-nav button {
  position: relative;
  flex: 1 1 50%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--green);
  cursor: pointer;
}
.fc-nav button:focus-visible { outline: 2px solid var(--green); outline-offset: -4px; }
.fc-nav span { position: absolute; left: 0; width: 100%; height: 33%; }
.fc-nav span:nth-child(1) { top: 0; }
.fc-nav span:nth-child(2) { top: 33%; }
.fc-nav span:nth-child(3) { top: 66%; }
.fc-nav i {
  position: absolute;
  top: 50%;
  width: 40px;
  height: 40px;
  margin-top: -20px;
  opacity: 0;
  pointer-events: none;
  transition: 0.2s;
}
.fc-left i { left: 6%; transform-origin: 100% 50%; }
.fc-right i { right: 6%; transform-origin: 0 50%; text-align: right; }
.fc-nav i svg { display: inline-block; }
.fc-nav button:hover i,
.fc-nav button:focus-visible i { opacity: 1; }
.fc-left span:nth-child(1):hover ~ i { transform: rotate(45deg); }
.fc-left span:nth-child(3):hover ~ i { transform: rotate(-45deg); }
.fc-right span:nth-child(1):hover ~ i { transform: rotate(-45deg); }
.fc-right span:nth-child(3):hover ~ i { transform: rotate(45deg); }

/* ---- the two hairlines before the clients ---------------------------------------
   Live: two separator rows, 1px of rgba(0,0,0,.08) across the container, 44px of
   space on each side of each (111px + 67px from the diagram to the headline,
   178px in all). Two wrappers so the margins cannot collapse into one gap. */
.home-sep { padding: 44px 0; }
.home-sep .separator-line { margin: 0; background: rgba(0, 0, 0, 0.08); }

/* ---- 5. clients --------------------------------------------------------------- */
.home-clients__lead {
  margin: 0 0 70px;
  color: var(--green);
  font-size: 16.8px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.05em;
  text-align: center;
  text-transform: uppercase;
}

.logo-carousel { position: relative; margin-bottom: 1.5rem; }
.logo-stage { display: flex; flex-wrap: wrap; }
.logo-item { flex: 0 0 auto; width: 25%; }
.logo-item img { display: block; width: auto; max-width: 100%; height: auto; margin: 0 auto; }   /* never scaled past its own 512px */
/* with JS: one moving track; the centre logo in full colour, the others in view
   faint (20%), the half logos at the edges at 50% */
.logo-carousel.is-live { overflow: hidden; }
.logo-carousel.is-live .logo-stage { flex-wrap: nowrap; will-change: transform; }
.logo-carousel.is-live .logo-item { opacity: 0.5; transition: opacity 0.4s; }
.logo-carousel.is-live .logo-item.is-active { opacity: 0.2; }
.logo-carousel.is-live .logo-item.is-center { opacity: 1; }
@media (max-width: 575px) { .logo-item { width: 100%; } }

@media (prefers-reduced-motion: reduce) {
  .fc-flip { transition: none !important; }
  .logo-carousel.is-live .logo-stage { transition: none !important; }
}

/* ---- components/about.css ---- */
/* ---- about-us --------------------------------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca, row for row (measured at 1440, 1024,
   768 and 390; the live page is WPBakery rows of Bootstrap columns):
     .ab-intro   rotating headline (32px / 46px) and the paragraph under it
     .home-mark  the 60 Years logo (shared with the homepage)
     .ab-why     "WHY US" and the Made in Canada stamp, fading in from the right
     .ab-stats   green band, three counters
     .ab-who     "Who We Are" on grey, two product cut-outs zooming in beside it
     .ab-team    the "Meet Our Team" lead-in, then the team cards (team.css)
   -------------------------------------------------------------------------- */

.ab-intro { padding-bottom: 3rem; overflow: hidden; }       /* live: pb-5 and overflow-hidden (the mask) */
.ab-headline {
  margin: 60px 0 15px;                   /* 15, not 16: the live paragraph starts 1px higher */
  font-size: 32px;
  font-weight: 400;
  line-height: 46px;
  letter-spacing: -0.05em;
  color: var(--ink);
  text-align: center;
}
.ab-headline .word-rotator-items.has-bg { background: #009b29; }
.ab-intro__col { padding-bottom: 35px; }              /* the text block's 35px, on the column so no p:last-child rule can drop it */
.ab-lede { margin: 0; text-align: center; }
.ab-lede b { font-weight: 900; }

.ab-why { padding-bottom: 3rem; }
.sicon-box { margin-bottom: 20px; }
.sicon-box h3 {
  margin: 0 0 12.6px;
  font-size: 16.8px;
  font-weight: 700;
  line-height: 26.4px;
  letter-spacing: -0.05em;
}
.ab-stamp { margin-bottom: 35px; text-align: center; }
.ab-stamp img { display: block; width: 200px; max-width: 100%; height: auto; margin: 0 auto; }

/* ---- the counters ------------------------------------------------------- */
.ab-stats {
  padding: 50px 0 48px;
  background: var(--green);
  color: #fff;
}
.stats-block { margin-bottom: 15px; text-align: center; }
.stats-icon { height: 25px; margin-bottom: 5px; font-size: 25px; line-height: 25px; }
.stats-icon .icon { display: inline-block; vertical-align: top; fill: currentColor; }
.stats-number {
  display: inline;
  padding: 8px 0;
  font-size: 35px;
  font-weight: 700;
  line-height: 35px;
}
.stats-text { font-size: 16.8px; font-weight: 200; line-height: 16.8px; }

/* ---- Who We Are ---------------------------------------------------------- */
.ab-who {
  padding: 60px 0 50px;
  background: var(--grey-band);
  overflow: hidden;               /* the cut-outs spill past the page's edges, as on the live page */
}
.ab-who__text { padding-bottom: 35px; }              /* 35px: the text block's own bottom margin */
@media (min-width: 576px) { .ab-who__text { margin-bottom: 3rem; } }
@media (min-width: 992px) { .ab-who__text { padding-right: 48px; margin-bottom: 0; } }
.ab-h2 {
  margin: 0 0 1rem;
  font-size: 25px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.05em;
}
.ab-h2 b { font-weight: 900; }
.ab-who .lead { margin-bottom: 1.25rem; }
.ab-who .lead span { font-weight: 400; }          /* the live lead's words sit in a 400-weight span */
.ab-who p:last-child { margin-bottom: 0; }
.ab-who p b { font-weight: 900; }

/* the two cut-outs: the shelf is pinned behind and to the left, the cart sits in
   the column and spills out to the right. Sizes are the column's: the cart is
   145% of it, the shelf 180% less 15px (live, fitted at 1440, 1200, 1024, 992,
   768, 700 and 576). */
.ab-who__pics { position: relative; padding-bottom: 50px; }
@media (min-width: 576px) { .ab-who__pics { margin-top: 3rem; padding-top: 3rem; } }
.ab-pic img { display: block; width: 100%; height: auto; }
.ab-pic--cart { position: relative; width: 145%; margin: -26% -45% 0 0; }
.ab-pic--shelf {
  position: absolute;
  top: 48px;
  left: 15px;
  display: none;
  width: calc(180% - 15px);
  margin: 10% 0 35px -80%;
}
@media (min-width: 576px) { .ab-pic--shelf { display: block; } }

/* ---- Meet Our Team lead-in ------------------------------------------------ */
.ab-team { padding: 80px 0 20px; }
.ab-team__col { padding-bottom: 35px; }
.ab-h2--team { line-height: 1.3; }
.ab-lead-light { margin: 0; }

@media (max-width: 575px) {
  .ab-headline { margin-top: 60px; }
}

/* ---- components/member.css ---- */
/* ---- a team member's own page ---------------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca (measured at 1440): the container with
   20px above and 40px below; a row of 32px padding holding the photo (5 of 12
   columns, 445px, first on a phone and on the right from 768px up) and the
   name, role, a hairline and a "Follow me" strip of round buttons. -------- */

.member-page { padding: 20px 0 40px; }
.member-overview { padding: 2rem 0; }
.member-overview__photo { margin-bottom: 24px; }
@media (min-width: 992px) { .member-overview__photo { margin-bottom: 0; } }
@media (min-width: 768px) { .member-overview__photo { order: 2; } }

.member-photo { position: relative; margin-bottom: 30px; }
.member-photo img { display: block; width: 100%; height: auto; border-radius: 4px; background: #fff; }
.member-photo:hover .zoom { opacity: 1; }
.member-photo .zoom { z-index: 1; }

.member-name {
  margin: 0;
  font-size: 1.875rem;
  font-weight: 300;
  line-height: 2.5rem;
  letter-spacing: -0.05em;
  color: var(--ink);
}
.member-name strong { font-weight: 700; }
.member-role {
  margin: 0 0 14px;
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 27px;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--green);
}
.member-rule { margin: 44px 0; background: rgba(0, 0, 0, 0.08); }

.member-share { display: flex; align-items: center; }
.member-share__label {
  margin-right: 0.9375rem;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 18px;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.share-links { display: flex; }
.share-links a {
  display: inline-block;
  width: 28px;
  height: 28px;
  margin: 2px;
  border-radius: 50px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  color: #222529;
  line-height: 28px;
  text-align: center;
  transition: 0.25s;
}
.share-links .icon { vertical-align: middle; }
.share-links a:hover { color: #fff; }
.share-links .share-linkedin:hover { background: #0073b2; }
.share-links .share-email:hover { background: #dd4b39; }
@media (max-width: 575px) { .member-role { line-height: 22.5px; } }

/* ---- components/services.css ---- */
/* ---- our-services ----------------------------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca (measured at 1440, 768 and 390): the logo,
   a centred heading and lead, three progress rings that fill on scroll with
   their step beneath, then a 400px Made in Canada stamp. ------------------- */

.sv-process { padding: 80px 0 70px; }
.sv-h2 {
  margin: 0 0 17px;
  font-size: 30px;
  font-weight: 700;
  line-height: 41px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
.sv-lead { margin: 0; }
.sv-h2, .sv-lead { text-align: center; }
.sv-rings { margin-top: 65px; }

/* a progress ring: 175px, a 13px #f1f1f1 track and a #00902a bar with round ends,
   starting at the top and running clockwise; the percentage sits in the middle in
   blue (#0088cc), 17px bold, 10px above centre (the live easy-pie-chart label) */
.ring { position: relative; height: 175px; margin-bottom: 40px; text-align: center; }
.ring__svg { display: block; margin: 0 auto; transform: rotate(-90deg); }
.ring__track { fill: none; stroke: #f1f1f1; stroke-width: 13; }
.ring__bar {
  fill: none;
  stroke: var(--green);
  stroke-width: 13;
  stroke-linecap: round;
  stroke-dasharray: 508.94px;
}
.ring__label {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  margin-top: -10px;
  font-size: 17px;
  font-weight: 700;
  line-height: 20px;
  color: #0088cc;
}

.sv-step { padding: 0 1rem; margin-bottom: 17px; text-align: center; }
.sv-step h3 {
  margin: 0 0 20px;
  font-size: 1.42857em;
  font-weight: 700;
  line-height: 1.6875rem;
  letter-spacing: -0.05em;
  color: var(--ink);
}

.sv-stamp { margin-bottom: 35px; text-align: center; }
.sv-stamp img { display: block; width: 400px; max-width: calc(100% - 40px); height: auto; margin: 0 auto; }
@media (min-width: 576px) { .sv-stamp img { max-width: 400px; } }

/* ---- components/contact.css ---- */
/* ---- contact-us -------------------------------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca (measured at 1440, 768, 390): the logo, a
   row of the form and the office block (25px above, 40px below), a hairline,
   and a 400px Made in Canada stamp. ----------------------------------------- */

.ct { padding-top: 25px; margin-bottom: 40px; }
.ct-info { margin-bottom: 0; }

.ct-h {
  margin: 0 0 14px;
  font-size: 1.42857em;
  font-weight: 600;
  line-height: 27px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
.ct-h strong { font-weight: 700; }
.ct-h--second { margin-top: 3rem; }

/* one line of the office block: an icon, then the words */
.ct-row { display: flex; align-items: center; margin-bottom: 15px; }
.ct-row p { margin: 0; }
.ct-row a,
.ct-row a[href^="tel:"]:not(.call-fab) { display: inline; min-height: 0; padding-block: 3px; }   /* keeps a 24px hit area without growing the line */
.ct-icon {
  flex: none;
  width: 14px;
  margin-right: 15px;
  text-align: center;
  line-height: inherit;
}
.ct-icon .icon { display: inline-block; vertical-align: middle; fill: currentColor; }
/* the three contact lines wear a thin blue ring (live: #0088cc, 25px + 1px border) */
.ct-icon--ring {
  width: 27px;
  height: 27px;
  border: 1px solid #0088cc;
  border-radius: 25px;
  color: #0088cc;
  line-height: 25px;
}

.ct-rule { height: 1px; margin: 0 20px 22px; background: rgba(0, 0, 0, 0.08); }
@media (min-width: 576px) { .ct-rule { margin-left: 30px; margin-right: 30px; } }
.ct-stamp { margin-bottom: 35px; text-align: center; }
.ct-stamp img { display: block; width: 400px; max-width: calc(100% - 40px); height: auto; margin: 0 auto; }
@media (min-width: 576px) { .ct-stamp img { max-width: 400px; } }
@media (max-width: 575px) { .ct-h { line-height: 22.5px; } }

/* ---- components/portfolio.css ---- */
/* ---- larkin-portfolio -----------------------------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca (measured at 1440, 1024, 768 and 390). Four
   sections — VERSA, Wire Decking, GuardLock, Rack Accesories — each a title that
   fades in letter by letter, a rotating line, some copy, a "featured" line with
   an Ask-about button, and a grid of product cards three across (the first six
   show; "Load more" shows the rest). Cards: a square picture that darkens on
   hover, then a grey caption with the name, a few lines and a red Read-more. */

.pf-head { padding-top: 50px; }
.pf-title {
  min-height: 2.75rem;
  margin: 0 0 2rem;
  font-size: 2.25rem;
  font-weight: 400;
  line-height: 2.75rem;
  letter-spacing: -0.05em;
  text-align: center;
  color: var(--ink);
}
.pf-title .letter { display: inline-block; }
.pf-rot {
  margin: 0 0 15px;
  font-size: 32px;
  font-weight: 300;
  line-height: 40px;
  letter-spacing: -0.05em;
  text-align: left;
  color: var(--ink);
}

.pf-rot--green .word-rotator-items { color: var(--green); }   /* the VERSA and Wire Decking lines; the other two stay dark */

.pf-prose { margin-bottom: 35px; }
.pf-prose--black { color: #000; }
.pf-prose h4 {
  margin: 0 0 14px;
  font-size: 1.42857em;
  font-weight: 700;
  line-height: 27px;
  letter-spacing: -0.05em;
  color: inherit;
}
.pf-prose ul { margin: 0 0 1rem; padding-left: 2rem; }
.pf-prose ul ul { margin: 0; }
.pf-grey,
.pf-prose .pf-grey { color: var(--body); }
.reg { font-weight: 400; }

.pf-feature { margin-bottom: 24px; }
.pf-lead { margin: 0; font-size: 1.42857em; color: #000; }
.pf-feature__text { padding-bottom: 35px; }      /* the text block's 35px, which shows when the button column stacks under it */
.pf-lead--grey { color: var(--body); }
.pf-btn-wrap { margin: 0 0 20px; }
.pf-gap { height: 32px; }

.pf-cards { padding: 50px 0 59px; overflow: hidden; }    /* the grid reaches 30px past the container, as the live row (overflow-hidden) clips it */
.pf-grid { display: flex; flex-wrap: wrap; margin: 0 -30px -30px 0; }
.pf-item { width: 100%; padding: 0 30px 30px 0; }
@media (min-width: 576px) { .pf-item { width: 33.3333%; } }
.pf-card__media { position: relative; overflow: hidden; aspect-ratio: 1; }
.pf-card__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pf-card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  opacity: 0;
  transition: opacity 0.5s;
}
.pf-card:hover .pf-card__media::after { opacity: 1; }
.pf-card__link { position: absolute; inset: 0; z-index: 1; }
.pf-card__body { padding: 10px 10px 31px; background: #f9f9f9; }
.pf-card__body h3 {
  margin: 0 0 14px;
  font-size: 1.42857em;
  font-weight: 600;
  line-height: 27px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
.pf-card__body p { color: var(--body); }
.pf-card__more { margin: 0; }
.pf-more { margin: 55px 0 -34px; text-align: center; }   /* the section keeps 59px under the cards; with a button that is 25px under it */
@media (max-width: 575px) { .pf-card__body h3 { line-height: 22.5px; } }

/* ---- components/projects.css ---- */
/* ---- projects -----------------------------------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca (measured at 1440): two projects side by
   side, each the client's logo, the project's name (30px, light, a link) and its
   render, centred, with 35px under each picture. 20px above and 40px below the
   whole. ------------------------------------------------------------------- */

.pj { padding: 20px 0 40px; }
.pj-fig { display: block; margin-bottom: 35px; text-align: center; }
.pj-fig img { display: block; max-width: 100%; height: auto; margin: 0 auto; }
.pj-title {
  margin: 0 0 32px;
  font-size: 1.875rem;
  font-weight: 300;
  line-height: 40px;
  letter-spacing: -0.05em;
  text-align: center;
}
.pj-title a { color: var(--ink); }
.pj-title a:hover { color: var(--green); }
@media (max-width: 575px) { .pj-title { line-height: 39px; } }

/* ---- components/pcard.css ---- */
/* ---- a project card ------------------------------------------------------------
   One square picture with its name on a dark plate, a green category tag, and on
   hover the picture grows 10%, darkens a little and two round buttons (open the
   page / see it larger) appear. Used by the related-projects band under a product
   (product.css) and by the project archives (archive.css). Measured on larkinco.ca
   at 1440 and 1024 (4 across), 768 (3) and 600 / 390; Porto's `thumb-info`. ---- */

.pcard { position: relative; overflow: hidden; border-radius: 4px; background: #f4f4f4; aspect-ratio: 1; }
.pcard img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 3px; transition: transform 0.3s; }   /* cover = the centre crop WordPress made of each thumbnail */
.pcard::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(23, 23, 23, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}
.pcard:hover img { transform: scale(1.1); }
.pcard:hover::after { opacity: 1; }
.pcard__link { color: inherit; }
.pcard__link::before { content: ""; position: absolute; inset: 0; z-index: 1; }
.pcard__title {
  position: absolute;
  left: 0;
  bottom: 13%;
  z-index: 2;
  max-width: 90%;
  padding: 13px 21px 2px;
  background: rgba(33, 37, 41, 0.8);
  color: #fff;
  transition: 0.3s;
}
.pcard:hover .pcard__title { background: #000; }
.pcard__name { display: block; font-size: 17px; font-weight: 600; line-height: 24px; letter-spacing: -0.05em; }
.pcard__type {
  display: block;
  width: fit-content;
  margin: 8px -2px -15px 0;
  padding: 2px 12px;
  border-radius: 2px;
  background: var(--green);
  font-size: 10.2px;
  font-weight: 600;
  line-height: 23.46px;
  text-transform: uppercase;
}
.pcard__actions {
  position: absolute;
  left: 3px;
  right: -3px;
  top: 52%;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 9.7px;
  margin-top: -22.5px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-10px);
  transition: transform 0.2s ease-out, opacity 0.2s ease-out;
}
.pcard:hover .pcard__actions,
.pcard__actions:focus-within { opacity: 1; transform: none; }
.pcard__go,
.pcard__zoom {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-top: 4.5px;
  border-radius: 50%;
  pointer-events: auto;
  transition: transform 0.3s;
}
.pcard__go { background: var(--green); color: #fff; }
.pcard__zoom { background: #fff; color: #777; }
.pcard:hover .pcard__go,
.pcard:hover .pcard__zoom { transform: scale(1.15); }   /* both icons, whenever the pointer is on the card */
.pcard__go .icon, .pcard__zoom .icon { fill: currentColor; }

/* Narrower than 992px the pictures are smaller and the plate and tag shrink with them. */
@media (max-width: 991px) {
  .pcard__name { font-size: 14px; }
  .pcard__type { font-size: 8.4px; line-height: 19.32px; }
}
@media (max-width: 575px) { .pcard__name { line-height: 20px; } }

/* ---- components/dots.css ---- */
/* ---- carousel dots -------------------------------------------------------------
   Owl Carousel's, as on larkinco.ca: a row of 8px circles, 25px high with 10px above
   (1.5625rem, so 23px on a phone), the current one dark green. Used under the related
   projects and under the project pictures. ---- */

.dots[hidden] { display: none; }
.dots { display: flex; justify-content: center; box-sizing: content-box; height: 1.5625rem; padding-top: 10px; }
.dot {
  width: 8px;
  height: 8px;
  margin: 5px 4px;
  padding: 0;
  border: 0;
  border-radius: 30px;
  background: #d6d6d6;
  cursor: pointer;
}
.dot.is-active { background: #007723; }

/* ---- components/product.css ---- */
/* ---- a product page (/portfolio/<name>/) -----------------------------------------
   Rebuilt 2026-09-30 from larkinco.ca (measured on Versa Rail at 1440): a title
   bar (back-to-list grid icon, the name, previous / next), a hairline, then the
   pictures one under another (7 of 12 columns, 30px apart) beside a panel (5 of
   12) that stays in view while they scroll: counts and date, the description,
   share buttons. Under it a grey band of related projects, four across. ---- */

.pp { padding: 20px 0 40px; }
.pp-title { margin-bottom: -15px; }
.pp-title .row { align-items: flex-start; }
.pp-all,
.pp-nav { margin-top: 11px; }
.pp-all a {
  display: block;
  width: 29px;
  height: 31px;
  color: var(--green);
  line-height: 28px;
}
.pp-all .icon { display: block; margin-left: 1px; fill: currentColor; }
.pp-nav { display: flex; justify-content: flex-end; }
.pp-nav a { display: block; width: 27px; height: 27px; color: var(--green); }
.pp-nav .icon { display: block; fill: currentColor; }
.pp-all a:hover,
.pp-nav a:hover { color: #00aa32; }
@media (max-width: 991px) { .pp-all, .pp-nav { display: none; } }   /* live drops the grid icon and the arrows below 992px */
.pp-name { text-align: center; }
.pp-name h1 {
  margin: 0;
  font-size: 1.875rem;               /* 30px, and 27.86px on a phone, where the page's rem is 92.86% */
  font-weight: 700;
  line-height: 40px;
  letter-spacing: -0.05em;
}
.pp-rule { margin: 44px 0; background: rgba(0, 0, 0, 0.08); }

.pp-gallery { margin: 0; padding: 0; list-style: none; }
.pp-item { margin: 0 0 30px; }
.pp-shot { position: relative; display: block; overflow: hidden; padding: 0; }   /* `main li a` would add 3px above and below */
.pp-shot img { display: block; width: 100%; height: auto; transition: transform 0.3s; }
.pp-shot:hover img,
.pp-shot:focus-visible img { transform: scale(1.1); }
/* hover: the picture darkens and a thin white cross says "open" */
.pp-shot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(33, 37, 41, 0.8);
  opacity: 0;
  transition: opacity 0.3s;
}
.pp-shot:hover::after,
.pp-shot:focus-visible::after { opacity: 1; }
.pp-plus {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 1;
  width: 30%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity 0.3s;
}
.pp-plus::before,
.pp-plus::after { content: ""; position: absolute; background: #fff; }
.pp-plus::before { left: 0; right: 0; top: 50%; height: 1px; }
.pp-plus::after { top: 0; bottom: 0; left: 50%; width: 1px; }
.pp-shot:hover .pp-plus,
.pp-shot:focus-visible .pp-plus { opacity: 1; }

.pp-side { position: sticky; top: 90px; padding-bottom: 1px; }
.pp-info { margin: 0 0 10px; padding: 0; list-style: none; color: #b1b1b1; }
.pp-info li { display: inline-block; font-size: 0.7875rem; margin-right: 8px; padding-right: 8px; border-right: 1px solid #e7e7e7; }
.pp-info li:last-child { margin: 0; padding: 0; border: 0; }
.pp-info a { color: #b1b1b1; }
.pp-info a:hover { color: var(--green); }
.pp-info .icon { margin-right: 4px; fill: currentColor; vertical-align: -2.6px; }
.pp-desc {
  margin: 20px 0 14px;
  font-size: 1.05rem;
  font-weight: 400;
  line-height: 18px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
@media (max-width: 575px) { .pp-desc, .pp-share__label { line-height: 15px; } }
.pp-desc strong { font-weight: 800; }
.pp-content { display: flow-root; margin-top: 10px; }   /* keeps the last block's 35px inside, as the live page does */
/* Each text block of the live description has 35px under it, the empty ones too (Versa Rail has two). */
.pp-row { display: flow-root; margin-bottom: 35px; }   /* flow-root: an empty row still takes its 35px, not collapsing into the next */
.pp-row > p:last-child { margin-bottom: 0; }
.pp-sep { margin: 0 0 22px; }
.pp-side .pp-rule { margin: 1.375rem 0; }
.pp-side .pp-rule--last { margin: 1.5rem 0; }
.pp-share { display: flex; align-items: center; margin-bottom: 1.5rem; }
.pp-share__label {
  margin-right: 15px;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 18px;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.pp-share .share-links { display: block; }           /* the buttons sit inline, a space apart, as on the live page */
.pp-share .share-links a[href] { padding: 0; line-height: 24px; font-size: 12.8px; }
.pp-share .share-facebook .icon { width: 8px; height: 14.4px; position: relative; top: -1px; }   /* live's Facebook "f" is a size larger than Font Awesome 6's */
.share-links .share-facebook:hover { background: #3b5a9a; }
.share-links .share-twitter:hover { background: #1aa9e1; }

/* ---- related projects --------------------------------------------------------- */
.pp-related { margin-top: 35px; padding: 5rem 0 4rem; background: var(--grey-band); }
.pp-related__h {
  margin: 0 0 14px;
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 27px;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.pp-related__h b { font-weight: 900; }
@media (max-width: 575px) { .pp-related__h { line-height: 22.5px; } }
.pp-rel { position: relative; }
.pp-rel__view { overflow: hidden; }
.pp-rel__stage { display: flex; }
.pp-rel__item { flex: 0 0 100%; }
@media (min-width: 576px) { .pp-rel__item { flex-basis: 50%; } }
@media (min-width: 768px) { .pp-rel__item { flex-basis: 33.3333%; } }
@media (min-width: 992px) { .pp-rel__item { flex-basis: 25%; } }
html:not(.js) .pp-rel__stage { flex-wrap: wrap; }
html:not(.js) .dots { display: none; }
.pp-body { align-items: flex-start; }                         /* so the side panel can stay in view */

/* ---- components/archive.css ---- */
/* ---- the project archives (/portfolios/, /portfolio_cat/<name>/) ----------------
   Rebuilt 2026-09-30 from larkinco.ca. A title (the full archive only), a row of
   category names, and the project cards four across from 992px, then 3 (768),
   2 (576) and 1. The original showed 10 at a time and loaded the next ten as you
   scrolled; 58-archive.js does the same from the next page's own address, and
   with JS off the numbered links under the grid take you there. ---- */

.arc { padding: 20px 0 40px; }

.arc-title {
  margin: 0 0 32px;
  font-size: 1.875rem;             /* 30px, 27.86px on a phone */
  font-weight: 300;
  line-height: 40px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
.arc-title strong { font-weight: 700; }

.arc-filter {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 0 2rem;
  padding: 0;
  list-style: none;
  font-size: 0.7rem;
  text-transform: uppercase;
}
.arc-filter a {
  display: inline-block;
  padding: 6px 12px;
  color: #777;
  transition: all 0.2s;
}
.arc-filter .is-active a { color: var(--green); border-bottom: 3px solid var(--green); }

.arc-grid { display: flex; flex-wrap: wrap; margin: 0 -15px; }
.arc-item { width: 100%; padding: 0 15px 30px; }
.arc-item[hidden] { display: none; }
@media (min-width: 576px) { .arc-item { width: 50%; } }
@media (min-width: 768px) { .arc-item { width: 33.3333%; } }
@media (min-width: 992px) { .arc-item { width: 25%; } }
.arc-item.is-new { animation: arcIn 0.4s ease-out; }
@keyframes arcIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .arc-item.is-new { animation: none; } }

/* The numbered links: the way on without JS. The original hid them once its own
   script took over, and so does this. */
.arc-pages { display: flex; flex-wrap: wrap; justify-content: center; margin-top: 20px; }
.js .arc-pages { display: none; }
.js .arc.has-error .arc-pages { display: flex; }
.arc-pages > * {
  display: inline-block;
  margin-left: -1px;
  padding: 8px 12px;
  border: 1px solid #e7e7e7;
  font-size: 14px;
  line-height: 16.8px;
  text-align: center;
  color: var(--green);
}
.arc-pages > :first-child { border-radius: 4px 0 0 4px; }
.arc-pages > :last-child { border-radius: 0 4px 4px 0; }
.arc-pages .is-current { border-color: var(--green); background: var(--green); color: #fff; }
.arc-pages a:hover { background: #f4f4f4; }
.arc-pages .icon { vertical-align: -2px; }

/* ---- components/spec.css ---- */
/* ---- /specifications/ ---------------------------------------------------------------
   The live page shows each PDF open on the page (the "PDF Embedder" plugin draws page
   one on a canvas, in a black-bordered grey frame), under a centred heading. Here each
   page one is a picture made from the PDF and links to the PDF itself. Measured on
   larkinco.ca at 1440 and 390: the frame is 2px wider than the column, the picture
   fills the column; headings 36px / 30px, the picture 20px under its heading. The
   original shows the Clip-On Divider sheet under "Beam Bracket" as well (no beam
   bracket sheet exists) and so does this. ---- */

.spec { padding: 20px 0 40px; }
.spec-h1,
.spec-h2 { margin: 0 0 0.625rem; text-align: center; letter-spacing: -0.05em; color: var(--ink); }
.spec-h1 { font-size: 2.25rem; font-weight: 400; line-height: 44px; }
.spec-h2 { font-size: 1.875rem; font-weight: 300; line-height: 40px; }
@media (max-width: 575px) { .spec-h1 { line-height: 36.6667px; } }
.pdf-embed {
  display: block;
  box-sizing: border-box;
  width: calc(100% + 2px);
  margin: 1.25rem 0 35px;
  padding: 0 0 0.7px 1px;                 /* the original's frame is 0.7px taller than its canvas + borders */
  border: 1px solid #000;
  background: #d3d3d3;
}
.pdf-embed img { display: block; width: calc(100% + 1px); max-width: none; height: auto; background: #fff; }
/* the frame's page is 1110 x 857 (a landscape sheet) or 1110 x 1436 (a portrait one) at full width, as drawn by the original */
.pdf-embed--wide img { aspect-ratio: 1110 / 857; }
.pdf-embed--tall img { aspect-ratio: 1110 / 1436; }

/* ---- components/policy.css ---- */
/* ---- the privacy policy -----------------------------------------------------------
   Plain text across the whole column, as on larkinco.ca: the section titles are bold
   body text, not headings, and the lists are indented 32px with no space between
   items. (Here the titles are still h2s, for anyone who navigates by heading.) ---- */

.pol { padding: 20px 0 40px; }
.pol h2 {
  margin: 0 0 1.25rem;
  font-size: inherit;
  font-weight: 900;
  line-height: inherit;
  letter-spacing: normal;
  color: inherit;
}
.pol ul { margin: 0 0 1rem; padding: 0 0 0 2rem; }
.pol > :last-child { margin-bottom: 1.25rem; }      /* the last paragraph keeps its space, as on the original */

/* ---- components/detail.css ---- */
/* ---- a project page (/stairs-parts-display-…/, /power-tool-display-…/) --------------
   Rebuilt 2026-09-30 from larkinco.ca, measured at 1440 on the Home Depot page: an
   intro (a 36px line with the accent-lettered client name, the "The New Way to ..."
   rotator, a 25px paragraph), a grey band with the pictures beside "Key Highlights",
   a closing paragraph, a green button, and a grey "In Store" band with the photos in
   two columns (one column under 1200px). ---- */

.pd-intro { padding: 50px 0 0; overflow: hidden; }    /* the overflow keeps the rotator's masked entrance inside it */
.pd-lead {
  margin: 0 0 35px;
  font-size: 1.25rem;
  font-weight: 300;
  line-height: 1.8rem;
  letter-spacing: -0.05em;
}
.pd-lead p { margin: 0; text-align: center; }
.pd-lead > p > span { font-size: 36px; }
.pd-lead .alternative-font { position: relative; top: 3px; margin-top: -15px; vertical-align: baseline; }   /* as measured on the live line; the site-wide rule sits it differently */
.pd-rot { margin: 0 0 15px; font-size: 32px; font-weight: 300; line-height: 40px; letter-spacing: -0.05em; text-align: left; color: var(--ink); }
.pd-rot .word-rotate-prefix { font-size: 32px; }
.pd-big { margin: 0 0 20px; font-size: 1.5625rem; font-weight: 400; line-height: 32px; letter-spacing: -0.05em; color: var(--ink); }
.pd-h { margin: 0 0 20px; font-size: 21px; font-weight: 400; line-height: 32px; letter-spacing: -0.05em; color: var(--ink); }
.pd-h b { font-weight: 900; }
.pd-big b { font-weight: 900; }

.pd-feature { padding: 80px 0 50px; background: #f7f7f7; }
.pd-text { margin: 0 0 35px; }
.pd-text p { margin: 0; }
.pd-text b { font-weight: 900; }

.pd-slides { margin: 0 0 20px; overflow: hidden; }
.pd-slides__track { display: flex; margin: 0; padding: 0; list-style: none; }
.pd-slides__track > li { flex: 0 0 100%; min-width: 0; }
.pd-slides__track img { display: block; width: 100%; height: auto; }
.pd-slides:not(.is-live) .pd-slides__track { display: block; }
.pd-slides:not(.is-live) .pd-slides__track > li { margin-bottom: 20px; }
.pd-slides.is-live .pd-slides__track { touch-action: pan-y; cursor: grab; }
.pd-slides.is-live .pd-slides__track:active { cursor: grabbing; }
.pd-slides.is-live img { user-select: none; -webkit-user-drag: none; }
.pd-slides:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

/* The closing paragraph sits in the middle half of the full page width (a 3 / 6 / 3 row
   inside the page's own 30px margins, not in the 1140px column). */
.pd-wide { padding: 50px 30px 0; }
.pd-wide .row { margin-left: -15px; margin-right: -15px; }
.pd-wide .row > * { margin: 0; }

.pd-cta { padding: 50px 0 70px; text-align: center; }     /* 50 above, the button's own 20 and 50 below */

.pd-store { padding: 80px 0 40px; background: #f7f7f7; }
.pd-h--center { margin: 0 0 0.5rem; line-height: 21px; text-align: center; }
.pd-store__sub { margin: 0 0 3rem; text-align: center; }
.pd-gal { margin: 0 -5px; }
.pd-gal figure { --c: 1; --r: 1600; margin: 0; padding: 5px; }       /* --c / --r: the column and the height in quarters of a px, set on each figure */
.pd-gal img { display: block; width: 100%; height: auto; }
@media (min-width: 1200px) {
  /* two columns, each picture under the shorter column; heights known (images are 550 wide), quarter-pixel rows (0.25 is exact in layout units; 0.1 is not) */
  .pd-gal { display: grid; grid-template-columns: 1fr 1fr; grid-auto-flow: row dense; grid-auto-rows: 0.25px; }
  .pd-gal figure { grid-column: var(--c); grid-row: span var(--r); }
}

/* Under 576px the paragraph type and the line heights of the headings step down (measured at 390). */
@media (max-width: 575px) {
  .pd-big, .pd-h { line-height: 26.6667px; }
  .pd-h--center { line-height: 21px; }
}
/* Under 768px the 3 / 6 / 3 row is one column; on a phone the paragraph takes the page's own 20px gutter. */
@media (max-width: 575px) { .pd-wide { padding-left: 20px; padding-right: 20px; } }

/* ---- components/notfound.css ---- */
/* ---- the 404 page ---------------------------------------------------------------------
   Porto's "page not found" layout as larkinco.ca shows it: a very large 404 with a page
   icon after it and one sentence, and beside it (below it under 992px) a short list of
   places to go. Measured at 1440, 1200, 992, 768, 576 and 390. The original's list also
   has an "FAQ's" entry; it linked nowhere there and this site has no such page, so it is
   left out. The "404" is a paragraph, not a heading: the page's heading is the hidden h1. ---- */

.nf { padding: 20px 0 40px; }
.nf-sec { margin: 50px 0; }
@media (max-width: 575px) { .nf-sec { margin: 0; } }

.nf-code {
  margin: 0 0 32px;
  font-size: 140px;
  font-weight: 600;
  line-height: 140px;
  letter-spacing: -10px;
  color: var(--ink);
}
.nf-code .icon { display: inline-block; width: 0.75em; height: 1em; margin: 2px -10px 0 0; fill: currentColor; vertical-align: top; }   /* sits 2px low, as the original's icon font does */
@media (max-width: 575px) {
  .nf-code { font-size: 100px; line-height: 100px; letter-spacing: normal; }
  .nf-code .icon { margin-right: 0; }
}
.nf-main { padding-bottom: 1.25rem; }               /* the sentence's own bottom margin (a last paragraph loses it) */
.nf-text { margin: 0; font-size: 1.4em; line-height: 36px; }

.nf-links-h {
  margin: 0 0 14px;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 27px;
  letter-spacing: -0.05em;
  color: var(--ink);
}
@media (max-width: 575px) { .nf-links-h { line-height: 22.5px; } }
.nf-links { margin: 0; padding: 0; list-style: none; }
.nf-links a {
  display: block;
  position: relative;
  padding: 8px 0 8px 20px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  font-size: 0.7875rem;
  line-height: 20px;
  color: #666;
}
.nf-links a:hover { color: var(--green); }
.nf-links .icon { position: absolute; left: 9px; top: 15.4px; fill: currentColor; }

/* ---- components/search.css ---- */
/* ---- the search page (/search/?s=...) ------------------------------------------------
   Laid out as on larkinco.ca: the results in a 9-column main area (the products as
   picture cards under "Results From Portfolios", everything else under "Miscellaneous"),
   a "Contact Us" panel in the 3-column side area. Measured at 1440. The original lists
   WordPress's own pages here (an unfinished "Order Tracking", "Portfolio-Test"); this
   searches only the site's real pages. ---- */

.se { padding: 20px 0 40px; }
.se-head { display: flex; align-items: center; margin: 0 0 25px; }
.se-head h2 {
  margin: 0;
  font-size: 1.5625rem;
  font-weight: 700;
  line-height: 32px;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.se-head::after { content: ""; flex: 1; height: 0; margin-left: 15px; border-top: 1px solid #e7e7e7; }
@media (max-width: 575px) { .se-head h2 { line-height: 26.6667px; } }

/* the product cards: 4 across from 1200px, 3 from 768, 2 from 576, as the original's grid */
.se .arc-item { width: 100%; }
@media (min-width: 576px) { .se .arc-item { width: 50%; } }
@media (min-width: 768px) { .se .arc-item { width: 33.3333%; } }
@media (min-width: 1200px) { .se .arc-item { width: 25%; } }

.se-items { display: flex; flex-wrap: wrap; margin: 0 -15px; }
.se-item { width: 100%; margin: 0 0 40px; padding: 0 15px 32px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); }
@media (min-width: 576px) { .se-item { width: 50%; } }
@media (min-width: 768px) { .se-item { width: 33.3333%; } }
@media (min-width: 1200px) { .se-item { width: 25%; } }
.se-item__t { margin: 0 0 16px; font-size: 21px; font-weight: 600; line-height: 27.3px; letter-spacing: -0.025em; color: var(--ink); }
.se-item__t a { color: inherit; }
.se-item__x { margin: 0 0 20px; }
.se-more { font-size: 13px; font-weight: 600; letter-spacing: -0.025em; text-transform: uppercase; color: var(--green); }

.se-nothing { margin: 0 0 15px; font-size: 1.875rem; font-weight: 300; line-height: 40px; letter-spacing: -0.05em; color: var(--ink); }
.se-alert {
  margin: 0 0 16px;
  padding: 16px;
  border: 1px solid #ceecf5;
  border-radius: 4px;
  background: #def2f8;
  color: #377385;
}
.se-alert a { color: inherit; text-decoration: underline; }
.se-form { display: flex; margin: 0 0 14px; }
.se-form input {
  flex: 1;
  min-width: 0;
  height: 36px;
  padding: 8px 12px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 3px 0 0 3px;
  font-size: 0.7rem;
  line-height: 16px;
  color: var(--ink);
}
.se-form button {
  width: 46px;
  height: 36px;
  margin-left: -1px;
  padding: 8px;
  border: 1px solid #0b0c0d;
  border-radius: 0 4px 4px 0;
  background: var(--ink);
  color: #fff;
  cursor: pointer;
}
.se-form .icon { fill: currentColor; }

.se-side-h {
  margin: 0 0 15px;
  font-size: 14px;
  font-weight: 700;
  line-height: 19.6px;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--ink);
}
.se-contact { margin: 0; padding: 0; list-style: none; font-size: 0.8125rem; line-height: 18px; }
.se-contact li { position: relative; margin: 0 0 10px; padding-left: 25px; }
.se-contact li:last-child { margin: 0; }
.se-contact .icon { position: absolute; left: 0; top: 2px; width: 16.9px; height: 16.9px; fill: var(--green); }
.se-contact span { display: inline; }
@media (max-width: 991px) { .se aside { margin-top: 30px; } }

/* ---- utilities.css ---- */
/* ---- utilities, motion, print ------------------------------------------- */

/* Any phone link anywhere is a tap target, including one written directly into
   page content. Enforce the WCAG 2.2 minimum (24x24) globally so a bare
   `tel:` link can never ship too small to hit on a phone — which would be a
   particularly bad failure on a business whose phone number is the product. */
/* `:not(.call-fab)` is load-bearing. An attribute selector outranks a class,
   and this file loads after the components, so without it this rule overrode
   `.call-fab { display: none }` and the mobile-only floating call button
   appeared at every width. */
a[href^="tel:"]:not(.call-fab) {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
}

/* Links inline inside a sentence get a WCAG 2.2 SC 2.5.8 exception, but their
   hit area is still only the ~19px text box. Vertical padding on an inline
   element grows the clickable box WITHOUT affecting the line box, so this
   costs nothing in layout and takes every prose link over the 24px minimum.
   Scoped to <main> so it never touches nav, topbar or footer, which set their
   own target sizes. */
main p a,
main li a,
a[href^="mailto:"] { padding-block: 3px; }

/* A list of links used for navigation rather than prose — the site map. These
   are not "inline in a sentence", so the 24x24 minimum applies in full. */
.link-list,
.link-list ul { margin: 0; padding-left: 1.1rem; }
.link-list ul { margin-left: 0.25rem; }
.link-list a {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  
}

@media print {
  .site-header,
.site-footer,
.call-fab,
.to-top,
.skip-link { display: none; }

  body { color: #000; background: #fff; }
  .section { padding: 1rem 0; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.75em; }
}
