/* ══════════════════════════════════════════════════════════════════════════
   UPLIFT · the homepage prototype's look, applied to an existing page
   without rebuilding it.

   Opt in by adding class="p-uplift" to <main> and linking this file. Nothing
   here can reach a page that has not opted in, and deleting the two lines
   reverts the page exactly.

   This is deliberately NOT the band system. It changes four things that the
   measurements said carry most of the difference between a template page and
   the homepage prototype:

     1. display type   52px/no tracking  ->  80px/-0.034em, and H2 off grey
     2. section rhythm 96/48/100/24      ->  one value
     3. grounds        white/near-white  ->  the real palette
     4. corners        10 values         ->  2 tokens  (see uplift-radius.css,
                                               generated per page)

   Markup stays exactly as it is.
   ══════════════════════════════════════════════════════════════════════════ */

.p-uplift{
  --ink:#0b2447; --teal:#1f7f79; --lift:#7fd4cf; --berry:#a33a57;
  --sand:#efe7d8; --clay:#e4b9a3; --sky:#cbdae4; --sage:#cbd6c2;
  --r-lg:14px; --r-sm:6px;
}

/* ── 1 · display type ───────────────────────────────────────────────────
   The single biggest tell. The live pages set headings at Outfit 700/600 with
   default tracking and 1.2 line-height, which is the browser's idea of a
   heading, not a designed one. Tightening tracking and leading is what makes
   large type look set rather than scaled up. */
.p-uplift :is(h1,h2){
  font-family:Outfit,sans-serif;
  font-weight:700;
  letter-spacing:-.034em;
  color:var(--ink);
  text-wrap:balance;
}
.p-uplift h1{font-size:clamp(2.7rem,5.4vw,5rem);line-height:.98;margin-bottom:.5em}
.p-uplift h2{font-size:clamp(1.9rem,3.4vw,3.6rem);line-height:1;margin-bottom:.6em}
.p-uplift h3{font-family:Outfit,sans-serif;font-weight:650;letter-spacing:-.018em;
  line-height:1.15;color:var(--ink)}

/* Headings that sit on a dark ground have to stay light. The live pages use
   .text-white on the section, so the colour above would otherwise win. */
.p-uplift .text-white :is(h1,h2,h3),
.p-uplift.text-white :is(h1,h2,h3){color:#fff}

/* ── 2 · section rhythm ─────────────────────────────────────────────────
   style.css carries `section{padding...!important}` at three separate
   breakpoints, so a plain rule here loses. Hence the !important: it is
   answering an !important, not being lazy. */
.p-uplift section{
  padding-top:clamp(3.4rem,8vw,7.5rem)!important;
  padding-bottom:clamp(3.4rem,8vw,7.5rem)!important;
}
/* The repeated [class] is deliberate, not a typo. style.css carries compound
   utilities like `.py-4.py-sm-5.py-md-6{padding:6rem!important}` at specificity
   (0,3,0), which outranks `.p-uplift section` at (0,2,0) even though both are
   !important. The result was a page where sections carrying all three utility
   classes sat at 96px and everything else at 115px: the uniform rhythm this
   file promises, except where it quietly lost. Each [class] adds (0,1,0),
   taking this to (0,3,1), which wins outright. */
.p-uplift section[class][class]{
  padding-top:clamp(3.4rem,8vw,7.5rem)!important;
  padding-bottom:clamp(3.4rem,8vw,7.5rem)!important;
}
/* The hero already has the fixed header above it and sets its own top. */
.p-uplift section[class][class].page-banner{padding-top:clamp(7rem,12vw,9.5rem)!important}

/* ── 3 · grounds ────────────────────────────────────────────────────────
   The pages already alternate backgrounds; they just alternate between white
   and two greys. Same markup, real palette. */
.p-uplift .bg-lgrey{background-color:var(--sand)!important}
.p-uplift .bg-white{background-color:#fff!important}
.p-uplift :is(.bg-grey,.bg-section-2,.bg-dblue){background-color:var(--ink)!important}
.p-uplift .bg-green{background-color:var(--sky)!important}
.p-uplift .bg-green :is(h1,h2,h3,p,li){color:var(--ink)}

/* service-pages-2026.css colours .service-area-group for a light section
   (h3 #1a1a2e, p #555). The rule above turns .bg-section-2 navy, which put
   those at about 2:1. web-design-orlando.html is the page that has them. */
.p-uplift :is(.bg-grey,.bg-section-2,.bg-dblue) .service-area-group h3{color:#fff}
.p-uplift :is(.bg-grey,.bg-section-2,.bg-dblue) .service-area-group p{color:#cdd7e5}

/* The swirl is decorative line-work drawn on a ::before pseudo-element, not a
   background-image on the section, which is why it survived the first pass.
   It is ornament rather than content, which is exactly what the homepage
   dropped, so it goes. */
.p-uplift .bg-swirl::before,
.p-uplift .bg-swirl::after{display:none!important}
.p-uplift .bg-swirl{background-image:none!important;background-color:var(--sand)!important}
.p-uplift .bg-swirl.bg-white{background-color:#fff!important}

/* The hero stays LIGHT on these pages, deliberately.
   The homepage hero is dark because it is carrying a video. Repeating that
   here would put the site header, which is transparent at the top of the page
   with teal links, on a navy ground it was never drawn for, and drag the whole
   light-nav problem onto every template page. Sand plus the big ink headline
   gets most of the homepage's character and none of that. */
.p-uplift .page-banner{background-color:var(--sand)!important}
.p-uplift .page-banner :is(h1,h2){color:var(--ink)}
.p-uplift .page-banner h1 :is(span,em){color:var(--teal);font-style:normal}

/* ── 4 · the accent ─────────────────────────────────────────────────────
   One accent, used sparingly: the second clause of a headline, the way the
   homepage does it. */
.p-uplift :is(h1,h2) span.accent,
.p-uplift :is(h1,h2) em{color:var(--teal);font-style:normal}
.p-uplift .text-white :is(h1,h2) span.accent,
.p-uplift .text-white :is(h1,h2) em{color:var(--lift)}

/* ── 5 · eyebrow ────────────────────────────────────────────────────────
   Optional. Add <p class="u-kick">Two or three words</p> above an H2. One
   attribute carries it (the tracking), not five at once. */
.p-uplift .u-kick{
  font-family:Outfit,sans-serif!important;
  font-size:.74rem!important;
  font-weight:400!important;
  letter-spacing:.16em!important;
  text-transform:uppercase;
  color:var(--teal)!important;
  margin:0 0 .9rem!important;
}
.p-uplift .text-white .u-kick{color:var(--lift)!important}

/* ══════════════════════════════════════════════════════════════════════════
   6 · THE HERO
   The veneer alone left these pages reading flat: same type, same flat ground,
   nothing to look at. The homepage hero works because there is something to
   see. So the hero goes dark, the copy comes off centre, and real client work
   sits beside it.
   Dark means the site header, transparent at the top of the page with teal
   links, now sits on navy. uplift.js adds .u-over to <html> while the hero is
   still behind the bar, and these rules answer it.
   ══════════════════════════════════════════════════════════════════════════ */
.p-uplift .page-banner{background-color:var(--ink)!important;overflow:hidden}
.p-uplift .page-banner :is(h1,h2){color:#fff}
.p-uplift .page-banner :is(p,li){color:#cdd7e5}
.p-uplift .page-banner h1 :is(span,em,b){color:var(--lift);font-style:normal}

/* Asymmetric: copy left, work right. Centring everything was the other thing
   making these read as a template. */
.p-uplift .u-hero-row{align-items:center}
.p-uplift .u-hero-copy{text-align:left!important}
.p-uplift .u-hero-copy p{margin-left:0!important;margin-right:0!important}
.p-uplift .u-hero-copy .trust-badges{justify-content:flex-start}
@media(max-width:991px){
  .p-uplift .u-hero-copy{text-align:center!important}
  .p-uplift .u-hero-copy p{margin-left:auto!important;margin-right:auto!important}
  .p-uplift .u-hero-copy .trust-badges{justify-content:center}
}

/* web-design-orlando.html carries a .trust-bar where the pages this file was
   first built against carry .trust-badges. Its items were coloured for a light
   hero (#1a1a2e), which lands at 1.1:1 on the navy ground. Same treatment as
   the hero's own body copy, and the same left/centre behaviour. */
.p-uplift .page-banner .trust-bar-item{color:#cdd7e5}
.p-uplift .u-hero-copy .trust-bar{justify-content:flex-start}
@media(max-width:991px){
  .p-uplift .u-hero-copy .trust-bar{justify-content:center}
}

/* The counters and their labels are dark-on-light by default. */
.p-uplift .page-banner :is(.number,.counter){color:#fff!important}
.p-uplift .page-banner .label{color:#9fb0c6!important}
.p-uplift .page-banner .round-icon-sm{background:rgba(255,255,255,.1)!important}
.p-uplift .page-banner .round-icon-sm img{filter:brightness(0) invert(1);opacity:.9}

/* ── the hero art ──────────────────────────────────────────────────────── */
.p-uplift .u-hero-art{position:relative}
.p-uplift .u-hero-art img{display:block;width:100%;height:auto;
  border-radius:var(--r-sm);
  box-shadow:0 2px 6px rgba(0,0,0,.28),0 22px 44px -18px rgba(0,0,0,.55)}

/* web design: a monitor, a tablet and a phone, at the sizes those things
   actually are relative to each other. */
.p-uplift .u-devices{display:flex;align-items:flex-end}
.p-uplift .u-devices .u-dv{margin:0}
.p-uplift .u-dv-monitor{width:66%}
.p-uplift .u-dv-tab{width:33%;margin-left:-8%!important;margin-bottom:6%}
.p-uplift .u-dv-phone{width:6.9%;margin-left:-2.5%!important;margin-bottom:2%}
.p-uplift .u-devices img{box-shadow:none;border-radius:0}

/* seo: two ranking grids, offset so they read as a pair rather than a table */
.p-uplift .u-grids{display:grid;grid-template-columns:1fr 1fr;gap:1rem;align-items:start}
.p-uplift .u-grids figure{margin:0}
.p-uplift .u-grids figure:last-child{margin-top:2.2rem}
.p-uplift .u-art-note{font-size:.76rem!important;color:#9fb0c6!important;
  letter-spacing:.01em;margin:.9rem 0 0!important;text-align:left}

/* ── light nav while the hero is behind the header ─────────────────────── */
html.u-over .site-header{background-color:transparent!important;box-shadow:none!important}
html.u-over .site-header .navbar-nav .nav-link,
html.u-over .site-header .navbar-brand{color:#fff!important}
html.u-over .site-header .navbar-nav .nav-link:hover,
html.u-over .site-header .navbar-nav .nav-link:focus{color:#7fd4cf!important}
html.u-over .site-header .navbar-brand img,
html.u-over .site-header .navbar-toggler-icon{filter:brightness(0) invert(1)}
html.u-over .site-header .navbar-toggler{border-color:rgba(255,255,255,.45)}

/* Two ranking grids side by side on a phone are two unreadable thumbnails.
   Stacked, each one is legible, and the pair still reads as a pair. */
@media(max-width:575px){
  .p-uplift .u-grids{grid-template-columns:1fr;gap:1.1rem}
  .p-uplift .u-grids figure:last-child{margin-top:0}
  .p-uplift .u-art-note{text-align:center}
}
/* The device trio shrinks to the point of being decorative on a phone. The
   monitor alone still says "we build websites" and stays readable. */
@media(max-width:575px){
  .p-uplift .u-dv-tab,.p-uplift .u-dv-phone{display:none}
  .p-uplift .u-dv-monitor{width:100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   7 · VIDEO HERO  (opt in with .u-has-video on the .page-banner)

   Decoration, so it stays out of the critical path exactly like the homepage
   reel: no src in the markup, preload="none", sources attached on idle after
   load, and only when the connection measures fast enough. Poster until then,
   poster forever on a slow link, which is a finished hero on its own.
   ══════════════════════════════════════════════════════════════════════════ */
.p-uplift .page-banner.u-has-video{position:relative;isolation:isolate}
/* The poster image itself is set inline per page, since each hero has its own
   loop. This supplies everything else, and the ink underneath means a hero
   that never gets either still has a real ground. */
.p-uplift .u-media{position:absolute;inset:0;z-index:0;
  background-color:var(--ink);background-position:center;
  background-size:cover;background-repeat:no-repeat}
.p-uplift .u-video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;opacity:0;transition:opacity .9s ease}
.p-uplift .u-video.is-playing{opacity:1}

/* Two layers. The footage sits at luminance 90-97 and barely moves, so it is
   mid-tone everywhere rather than dark: the copy side has to be pulled down
   hard, and the right stays open so the laptop reads. The second layer is a
   header-height fade, because the top strip measures 91-95 and white nav links
   on that go thin. */
.p-uplift .u-scrim{position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(11,36,71,.55) 0,rgba(11,36,71,0) 170px),
             linear-gradient(90deg,rgba(11,36,71,.95) 0%,rgba(11,36,71,.88) 36%,
                                   rgba(11,36,71,.58) 68%,rgba(11,36,71,.40) 100%)}
@media(max-width:991px){
  /* Stacked, the copy is centred over the whole width, so the angled scrim
     would leave the right half of the text on open footage. */
  .p-uplift .u-scrim{background:linear-gradient(180deg,rgba(11,36,71,.80) 0%,rgba(11,36,71,.88) 100%)}
}
.p-uplift .page-banner.u-has-video .caption{position:relative;z-index:2}
@media(prefers-reduced-motion:reduce){.p-uplift .u-video{display:none}}

/* ── thin strips keep their own rhythm ──────────────────────────────────
   The uniform padding above assumes every section is a content band. It is
   not: a page that sets py-3 on a section, or calls it a banner, meant a thin
   strip. The award banner has 80px of content and was getting 115px of padding
   on each side, so a one-line credit sat in 310px of empty sand.
   Respect the author's own signal instead of overriding it. */
.p-uplift section[class][class]:is(.py-1,.py-2,.py-3,.award-banner,.logo-strip){
  padding-top:clamp(1.5rem,2.4vw,2.2rem)!important;
  padding-bottom:clamp(1.5rem,2.4vw,2.2rem)!important;
}
/* Given the strip is now its own size, the badge can carry it properly. */
.p-uplift .award-banner img{width:104px;height:auto}
.p-uplift .award-banner :is(b,strong,.fw-bold){font-size:1.06rem}

/* style.css tucks the section right after the hero up against it:
   `.page-banner + section.py-4.py-sm-5.py-md-6{padding:1.5rem!important}`,
   specificity (0,4,1). That is correct on the live page, where the hero and
   the band below share the swirl background and flow into each other. Here the
   hero is a distinct dark band, so the tuck left a full content section
   squashed to 24px of top padding while every other band sat at 115.
   The third [class] is what clears (0,4,1); this lands at (0,5,1).
   The :not(:is(...)) matters: on the web design page the section after the
   hero IS the award strip, and without it this rule put that strip straight
   back to 115px. :is() reports the specificity of its heaviest argument, so
   the exclusion costs (0,1,0) rather than one per class. */
.p-uplift .page-banner + section[class][class][class]:not(:is(.py-1,.py-2,.py-3,.award-banner,.logo-strip)){
  padding-top:clamp(3.4rem,8vw,7.5rem)!important;
}

/* ── the ranking grids, in the results band ────────────────────────────
   Moved out of the hero and down to where the Search Console numbers already
   live. Two different kinds of evidence for the same claim read stronger side
   by side than either does alone behind a headline. Light ground here, so the
   note is grey rather than the hero's pale blue. */
.p-uplift .u-gridpair{display:grid;grid-template-columns:1fr 1fr;gap:1.1rem;margin-top:2.4rem}
.p-uplift .u-gridpair figure{margin:0}
.p-uplift .u-gridpair img{display:block;width:100%;height:auto;border-radius:var(--r-sm);
  box-shadow:0 1px 3px rgba(11,36,71,.16),0 12px 26px -14px rgba(11,36,71,.42)}
.p-uplift .u-gridnote{font-size:.78rem!important;color:#6b7280!important;margin:.85rem 0 0!important}
@media(max-width:575px){.p-uplift .u-gridpair{grid-template-columns:1fr}}

/* ── links inside tables ───────────────────────────────────────────────
   A column of underlined teal names turns a results table into a list of
   links: the eye reads the decoration before the data. The client names are
   content first, so they stay ink and undecorated, and only announce
   themselves as links on hover or keyboard focus. The footnote under the table
   already tells people the names are clickable.
   Each anchor carries an inline style="color:#4ba29f;font-weight:500", which
   beats any stylesheet selector, so these have to be !important to answer it. */
.p-uplift table a{
  color:var(--ink)!important;
  text-decoration:none!important;
  font-weight:600!important;
}
.p-uplift table a:hover,
.p-uplift table a:focus-visible{
  color:var(--teal)!important;
  text-decoration:underline!important;
  text-underline-offset:3px;
}

/* These carry style="text-decoration:none" so style.css's blanket
   `a:not(...)...{text-decoration:underline!important;font-weight:bold!important}`
   stops matching, which hands control back here. The underline stays, because
   these links sit in body text and colour alone is not an accessible way to
   mark a link. It is just quiet: ink rather than teal, hairline rather than
   full weight, and it comes up to strength on hover. */
.p-uplift .u-tablelink{
  color:var(--ink)!important;
  font-weight:600!important;
  text-decoration:underline!important;
  text-decoration-color:rgba(11,36,71,.3)!important;
  text-decoration-thickness:1px!important;
  text-underline-offset:3px;
  transition:text-decoration-color .15s ease,color .15s ease;
}
.p-uplift .u-tablelink:hover,
.p-uplift .u-tablelink:focus-visible{
  color:var(--teal)!important;
  text-decoration-color:var(--teal)!important;
}

/* The hero poster, as an element rather than a background. See the note in the
   build script: a CSS background cannot be found by the preload scanner, so it
   waits for CSS parse plus layout before it even starts downloading. That cost
   the homepage about 2.7s of LCP on a throttled phone. */
.p-uplift .u-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* The signature moment: one client's real click history drawing itself.
   Pattern 1 from the concept-motion playbook.

   is-armed is added only from JS, so with JavaScript off the line is simply
   there, fully drawn. Under prefers-reduced-motion it also lands finished
   rather than animating. The moment is the only thing on this page that
   moves on scroll; everything else stays at rest. */
.p-uplift .clickline { margin: 0; }
.p-uplift .clickline-svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}
.p-uplift .clickline-path {
    fill: none;
    stroke: #22675a;
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.p-uplift .clickline-dot { fill: #22675a; }
.p-uplift .clickline-dot--peak { fill: #0b2447; }

.js .p-uplift .clickline.is-armed .clickline-path {
    stroke-dasharray: var(--len);
    stroke-dashoffset: var(--len);
}
.js .p-uplift .clickline.is-armed.is-in .clickline-path {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 1.8s cubic-bezier(.22,1,.36,1);
}
.js .p-uplift .clickline.is-armed .clickline-dot { opacity: 0; }
.js .p-uplift .clickline.is-armed.is-in .clickline-dot {
    opacity: 1;
    transition: opacity .4s ease 1.3s;
}

.p-uplift .clickline-key {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.5rem;
    margin-top: 1rem;
    font-size: 0.9rem;
    color: #4e5c6d;
}
.p-uplift .clickline-key b {
    font-family: "Outfit", "Outfit Fallback Roboto", "Outfit Fallback Arial", sans-serif;
    font-size: 1.15rem;
    color: #1a1a2e;
    margin-right: .35rem;
}
.p-uplift .clickline-key--peak b { color: #0b2447; }

@media (prefers-reduced-motion: reduce) {
    .js .p-uplift .clickline.is-armed .clickline-path { stroke-dashoffset: 0; transition: none; }
    .js .p-uplift .clickline.is-armed .clickline-dot { opacity: 1; transition: none; }
}
