/* ══════════════════════════════════════════════════
   AI OPTIMIZATION (MARKET) — templates/page-ai-optimization.php
   ══════════════════════════════════════════════════

   CASCADE — and it is not the order the handoff doc used to give:

       assets/css/pages/ai-optimization.css   (this file, first)
       assets/css/global.css
       assets/css/interior.css                (last, wins)

   functions.php enqueues interior.css with `array( 'seolocale-global' )`
   as its dependency, so on every interior page it loads after both of
   the others. interior.css is the interior design system and it owns
   more than it looks like: hero typography, the whole FAQ accordion,
   card radii, long-form prose size and ink, and the closing CTA
   including the team photo behind it.

   So a rule here for a shared component may well be doing nothing.
   .eyebrow, .btn*, .crumbs, .faq-plus, .seo-services-list and its
   marker, and .resources / .res-card are not redeclared below for
   that reason. A measured audit found roughly 60 more declarations
   in this file that change no computed value at any of the four
   viewports — they are left in place for now rather than removed on
   a half-checked list, because a first attempt at removing them
   silently changed the hero headline's margin and the intro
   paragraph's measure at 390px. Removing them wants the
   snapshot-equivalence method, not a reading.

   The page is built to serve a market per page, so nothing here
   assumes Philadelphia — no copy, no image, no aspect ratio is tied
   to one city.
   ══════════════════════════════════════════════════ */


/* ═══════ HERO ═══════ */

.hero{position:relative;padding:40px 0 110px;overflow:hidden;background:var(--obsidian);}

.hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 55% 65% at 78% 22%,rgba(22,192,183,0.06) 0%,transparent 60%),radial-gradient(ellipse 45% 55% at 10% 88%,rgba(33,62,89,0.14) 0%,transparent 60%);}

/* Single column, unlike the engine pages. Those lead with a mockup
   of the assistant they are about; this page is about a market
   rather than one product, so there is no interface to draw and a
   centred column reads better than an empty right half. */
.aiopt-hero-inner{position:relative;z-index:1;max-width:820px;}

/* ═══════ Hero panel ═══════

   Two columns once the page has a panel. `.hero-grid` is the class
   every other hand-built service page uses, so its children get
   min-width:0 from global.css:2319 for free — but NOT its stacking:
   global.css's one-class rule loses to the two-class rule below, so
   the breakpoint is restated at the foot of this block.

   The max-width above is dropped in the two-column case: 820px was
   the measure of a single text column, and it would squeeze both. */
.aiopt-hero-inner.hero-grid{display:grid;grid-template-columns:1fr 1.02fr;gap:56px;align-items:center;max-width:1200px;}

.aio-serp-wrap{position:relative;width:100%;}

/* The rank chip, overlapping the card's top-left corner. */
.aio-serp-badge{position:absolute;top:-14px;left:18px;z-index:2;display:inline-flex;align-items:center;gap:7px;
  padding:7px 14px;border-radius:999px;background:var(--teal);color:#04262b;
  font-size:12px;font-weight:800;letter-spacing:0.02em;box-shadow:0 8px 24px rgba(0,0,0,0.35);}

/* A screenshot of a search result, so it is a white card in Arial on
   a dark hero rather than anything in the site's own type. */
.aio-serp{background:#fff;border-radius:16px;overflow:hidden;font-family:Arial,Helvetica,sans-serif;color:#202124;
  box-shadow:0 40px 100px rgba(0,0,0,0.55),0 0 0 1px rgba(0,0,0,0.08);}

.aio-serp-bar{display:flex;align-items:center;gap:14px;padding:14px 16px;border-bottom:1px solid #ebedf0;}

.aio-serp-logo{font-size:17px;font-weight:700;letter-spacing:-0.5px;flex:0 0 auto;}
.aio-serp-logo span:nth-child(1){color:#4285f4;}
.aio-serp-logo span:nth-child(2){color:#ea4335;}
.aio-serp-logo span:nth-child(3){color:#fbbc05;}
.aio-serp-logo span:nth-child(4){color:#4285f4;}
.aio-serp-logo span:nth-child(5){color:#34a853;}
.aio-serp-logo span:nth-child(6){color:#ea4335;}

.aio-serp-box{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:9px;
  padding:8px 14px;border:1px solid #dfe1e5;border-radius:999px;font-size:13px;color:#3c4043;}
.aio-serp-box i{color:#9aa0a6;font-size:12px;}
.aio-serp-box span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* ── The typing animation ──
   Every rule below is gated on .is-armed, which the JS adds to the
   wrapper before it hides anything. Without scripts the class never
   arrives and the panel is the finished search: the query printed in
   full, every row visible, no caret. That is also what the render
   harness writes, so what gets measured is what a reader without JS
   sees. */

.aio-serp-caret{display:none;width:1.5px;height:15px;margin-left:1px;background:#3c4043;flex:0 0 auto;}
.is-armed .aio-serp-caret{display:inline-block;animation:aio-blink 1.05s steps(1) infinite;}
.is-armed.is-searched .aio-serp-caret{animation:none;opacity:0;}
@keyframes aio-blink{0%,49%{opacity:1}50%,100%{opacity:0}}

/* The rows keep their space while hidden, so nothing jumps when they
   arrive — the card is the same height throughout. */
.is-armed .aio-serp-row{opacity:0;transform:translateY(7px);}
.is-armed .aio-serp-row.is-in{opacity:1;transform:none;transition:opacity .34s ease,transform .34s cubic-bezier(.2,.7,.3,1);}

.is-armed .aio-serp-pin{opacity:0;transform:rotate(-45deg) scale(.4);}
.is-armed .aio-serp-pin.is-in{opacity:1;transform:rotate(-45deg) scale(1);transition:opacity .3s ease,transform .38s cubic-bezier(.3,1.4,.5,1);}

/* Asked for less motion, get the finished state — the JS returns
   before arming, so this is belt and braces for a class left behind
   by a cached page. */
@media(prefers-reduced-motion:reduce){
  .is-armed .aio-serp-row,
  .is-armed .aio-serp-pin{opacity:1;transform:none;}
  .is-armed .aio-serp-caret{display:none;}
}

.aio-serp-tabs{display:flex;gap:20px;padding:0 18px;border-bottom:1px solid #ebedf0;font-size:12px;color:#5f6368;}
.aio-serp-tabs span{padding:10px 0;}
.aio-serp-tabs .active{color:#1a73e8;box-shadow:inset 0 -3px 0 #1a73e8;font-weight:600;}

/* A suggestion of a map, not a map. Flat color and three pins reads
   as one at this size and costs nothing to load. */
.aio-serp-map{position:relative;height:104px;background:
  linear-gradient(0deg,rgba(0,0,0,0.04),rgba(0,0,0,0.04)),
  repeating-linear-gradient(90deg,#e8eaed 0 1px,transparent 1px 38px),
  repeating-linear-gradient(0deg,#e8eaed 0 1px,transparent 1px 34px),#f1f3f4;}

.aio-serp-pin{position:absolute;width:11px;height:11px;border-radius:50% 50% 50% 0;
  transform:rotate(-45deg);background:#9aa0a6;box-shadow:0 1px 3px rgba(0,0,0,0.3);}
.aio-serp-pin.is-client{width:16px;height:16px;background:#ea4335;z-index:1;}

.aio-serp-body{padding:14px 18px 18px;}

.aio-serp-hit,
.aio-serp-rival{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid #f1f3f4;}
.aio-serp-rival:last-child{border-bottom:0;}

.aio-serp-hit{background:linear-gradient(90deg,rgba(22,192,183,0.10),transparent 70%);
  margin:0 -18px;padding-left:18px;padding-right:18px;border-left:3px solid var(--teal);}

.aio-serp-rank{flex:0 0 auto;width:22px;height:22px;border-radius:50%;background:var(--teal);color:#04262b;
  font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center;}
.aio-serp-rank.is-dim{background:#e8eaed;color:#80868b;}

.aio-serp-hit-text{min-width:0;}
.aio-serp-name{font-size:14px;line-height:1.35;color:#1a0dab;font-weight:600;margin-bottom:3px;}
.aio-serp-meta{font-size:12px;color:#3c4043;line-height:1.5;}
.aio-serp-tag{font-size:12px;color:#5f6368;line-height:1.5;margin-top:2px;}

@media(max-width:900px){
  /* One column, stated here rather than left to global.css:2318.
     That rule is `.hero-grid{grid-template-columns:minmax(0,1fr)}` —
     one class — and the two-column rule above is `.aiopt-hero-inner
     .hero-grid`, two. Specificity beats source order, so the hero
     stayed two columns at 390px: a 153px text column beside a 156px
     card. The comment above used to claim global.css handled this. */
  .aiopt-hero-inner.hero-grid{grid-template-columns:minmax(0,1fr);gap:40px;}
  /* The panel is decoration; on a phone the copy and the button
     matter more, so it goes under them rather than above. */
  .aio-serp-wrap{order:2;}
}

.hero-h1{font-size:clamp(36px,3.8vw,56px);font-weight:900;line-height:1.05;letter-spacing:-1.5px;margin-bottom:20px;}

.hero-h1 em{font-style:normal;color:var(--teal);}

.hero-p{font-size:18px;color:var(--muted);line-height:1.75;margin-bottom:28px;max-width:640px;}
.hero-local{font-size:14.5px;color:var(--muted);margin:-14px 0 28px;max-width:640px;}
.hero-local a{color:var(--teal);font-weight:700;text-decoration:underline;text-underline-offset:3px;text-decoration-color:rgba(22,192,183,0.4);}
.hero-local a:hover{color:#1ad4ca;text-decoration-color:#1ad4ca;}

.hero-btns{display:flex;gap:14px;flex-wrap:wrap;}

.aiopt-proof{display:flex;align-items:center;flex-wrap:wrap;gap:14px 36px;margin-top:40px;padding-top:28px;border-top:1px solid rgba(22,192,183,0.16);}

.aiopt-proof-item{display:flex;align-items:baseline;gap:10px;}

.aiopt-proof-n{font-size:30px;font-weight:900;letter-spacing:-1px;color:var(--teal);line-height:1;}

.aiopt-proof-l{font-size:13px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted);}


/* ═══════ WHAT IT IS — four cards ═══════ */

.services{padding:clamp(72px,9vw,120px) 0;background:var(--obsidian);position:relative;z-index:2;overflow:hidden;}

.svc-wrap{position:relative;z-index:1;}

.svc-head{text-align:center;max-width:760px;margin:0 auto 56px;}

.svc-head h2{font-size:clamp(30px,3.6vw,48px);font-weight:900;letter-spacing:-1.2px;line-height:1.05;margin-bottom:14px;}

.svc-head h2 em{font-style:normal;color:var(--teal);}

.svc-head p{color:var(--muted);font-size:17px;line-height:1.7;}

/* auto-fit rather than repeat(4,1fr): the card count is an editable
   repeater, so three or five cards have to lay out as well as four. */
.svc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:22px;max-width:1200px;margin:0 auto;}

.svc-card{position:relative;background:linear-gradient(180deg,rgba(12,26,38,0.85),rgba(5,11,18,0.7));border:1px solid rgba(22,192,183,0.1);border-radius:18px;padding:32px 28px;transition:all 0.35s;overflow:hidden;}

.svc-card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:var(--text-grad);opacity:0;transition:opacity 0.3s;}

.svc-card:hover{transform:translateY(-5px);border-color:rgba(22,192,183,0.25);box-shadow:0 24px 60px rgba(0,0,0,0.4);}

.svc-card:hover::before{opacity:1;}

.svc-card-icon{width:52px;height:52px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-size:22px;margin-bottom:18px;background:rgba(22,192,183,0.08);color:var(--teal);transition:all 0.3s;}

.svc-card:hover .svc-card-icon{background:var(--teal);color:var(--obsidian);}

.svc-card h3{font-size:19px;font-weight:900;letter-spacing:-0.3px;margin-bottom:10px;}

.svc-card p{font-size:15px;color:var(--muted);line-height:1.7;margin:0;}


/* ═══════ IMAGE + TEXT BLOCKS ═══════ */

.aiopt-splits{padding:clamp(72px,9vw,120px) 0;background:var(--surface);position:relative;z-index:2;}

.aiopt-split{display:grid;grid-template-columns:1fr 1.1fr;gap:clamp(32px,5vw,64px);align-items:center;}

.aiopt-split + .aiopt-split{margin-top:clamp(56px,7vw,96px);}

/* The editor picks the side per block, so the flip is a class and
   not an :nth-child rule — inserting a block in the middle must not
   re-order the ones after it. */
.aiopt-split.is-flipped .aiopt-split-media{order:2;}

.aiopt-split-media{border-radius:18px;overflow:hidden;border:1px solid rgba(22,192,183,0.14);background:#0a1620;box-shadow:0 24px 60px rgba(0,0,0,0.35);}

/* Images come from the media library at whatever crop the editor
   uploaded. A fixed aspect ratio plus cover keeps two blocks the
   same height without demanding a particular source image. */
.aiopt-split-media img{display:block;width:100%;height:100%;aspect-ratio:16/10;object-fit:cover;}

.aiopt-split-body h2{font-size:clamp(26px,2.9vw,40px);font-weight:900;letter-spacing:-0.8px;line-height:1.1;margin-bottom:18px;}

.aiopt-split-body p{font-size:17px;color:var(--muted);line-height:1.8;margin-bottom:16px;}

.aiopt-split-body p:last-child{margin-bottom:0;}

@media (max-width:900px){
  .aiopt-split{grid-template-columns:minmax(0,1fr);gap:28px;}
  /* Without this the flipped block puts its image below its text on
     a phone, so alternate blocks read in alternate orders. */
  .aiopt-split.is-flipped .aiopt-split-media{order:0;}
}


/* ═══════ FAQ ═══════ */

.faq{padding:clamp(72px,9vw,120px) 0;background:var(--surface);position:relative;z-index:2;}

.faq-head{position:relative;z-index:1;text-align:center;max-width:760px;margin:0 auto 56px;}

.faq-head h2{font-size:clamp(30px,3.4vw,48px);font-weight:900;letter-spacing:-1px;line-height:1.05;margin-bottom:14px;}

.faq-head h2 em{font-style:normal;color:var(--teal);}

.faq-head p{color:var(--muted);font-size:16px;line-height:1.6;}

.faq-items{position:relative;z-index:1;max-width:860px;margin:0 auto;}

.faq-item{background:rgba(22,192,183,0.02);border:1px solid rgba(22,192,183,0.08);border-radius:14px;padding:22px 28px;cursor:pointer;margin-bottom:12px;transition:all 0.25s;}

.faq-item:hover{background:rgba(22,192,183,0.05);border-color:rgba(22,192,183,0.18);}

.faq-item.open{background:rgba(22,192,183,0.06);border-color:rgba(22,192,183,0.22);}

.faq-q{font-size:17px;font-weight:700;display:flex;justify-content:space-between;align-items:center;gap:20px;}

.faq-a{color:var(--muted);font-size:15px;line-height:1.75;max-height:0;overflow:hidden;transition:max-height 0.4s ease,padding 0.3s;}

/* CAP: 2400px, over interior.css's :where() default of 900px.
   These two answers are the whole of live's FAQ and each one is a
   small article — four <h4> subheads and eleven paragraphs in the
   first, a four-step <ol> in the second. Measured with
   tools/page-restore/layout-pass.js, the two answers need:

       1280px viewport   1052 / 1010
        900px viewport   1078 / 1036
        760px viewport   1235 / 1220
        390px viewport   2224 / 2105   <- worst case

   2224 was the number the cap had to clear when this page was the
   only one on the template; 390px is where the column is narrowest
   and every paragraph wraps hardest.

   /home-services-seo/ then arrived with a single answer that live
   fills with seven subheadings and six bullet lists, and it needs:

       1280px viewport   2195
        900px viewport   2248
        760px viewport   2379
        390px viewport   3788   <- worst case on the whole template

   3788 is what the cap has to clear now, and 2400px clipped 1388px
   of that answer off the bottom. The rest is headroom, and it is
   deliberate for a reason that does not apply to the other service
   pages: these answers are an ACF repeater an editor can lengthen
   without ever touching CSS.
   `CAP=340px node tools/page-restore/layout-pass.js ai-optimization`
   is the control that proves this check can fail.

   This works from a page stylesheet only because interior.css sets
   its 900px default inside :where(), which has zero specificity. A
   plain `.faq-item.open .faq-a` there would beat this file on order
   no matter what it said. */
.faq-item.open .faq-a{max-height:4600px;padding-top:16px;}

.faq-a p{margin:0 0 14px;}

.faq-a p:last-child{margin-bottom:0;}

.faq-a strong{color:var(--text);font-weight:800;}

/* The subheads inside an answer. global.css's reset zeroes their
   margins, so without this the answer is an undifferentiated wall. */
.faq-a h4{font-size:16px;font-weight:900;color:var(--text);margin:22px 0 10px;letter-spacing:-0.2px;}

.faq-a h4:first-child{margin-top:0;}

/* The blueprint steps. list-style and padding are both zeroed by the
   global reset, so a bare <ol> renders as unnumbered paragraphs. */
.faq-a ol{list-style:decimal;padding-left:22px;margin:0 0 14px;display:flex;flex-direction:column;gap:18px;}

.faq-a ol li{padding-left:4px;}

.faq-a ol li::marker{color:var(--teal);font-weight:900;}

.faq-a ol li > strong{display:block;font-size:16px;margin-bottom:8px;}


/* ═══════ TEAM VIDEO ═══════ */

/* interior.css gives .video-block its seam but no padding, and
   global.css's `*{padding:0}` reset zeroes it. The inner grid and
   the frame are page-level on every service page too. */

.video-block{padding:clamp(64px,7vw,104px) 0;}

.video-block-inner{display:grid;grid-template-columns:1.1fr 1fr;gap:50px;align-items:center;}

.video-block h2{font-size:clamp(28px,3vw,42px);font-weight:900;letter-spacing:-0.5px;line-height:1.1;margin-bottom:18px;}

.video-block h2 em{font-style:normal;color:var(--teal);}

.video-block p{color:var(--muted);font-size:17px;line-height:1.75;margin-bottom:24px;}

.video-label{font-size:11px;color:var(--muted);font-weight:800;letter-spacing:2px;text-transform:uppercase;margin-bottom:6px;}

.video-frame{position:relative;aspect-ratio:16/9;width:100%;background:#0a1620;border:1px solid rgba(22,192,183,0.15);border-radius:16px;overflow:hidden;}

.video-frame iframe{display:block;width:100%;height:100%;border:0;}

@media (max-width:900px){.video-block-inner{grid-template-columns:minmax(0,1fr);gap:32px;}}

/* The award badge under the video, rendered only where a preset
   names a badge image. It sits below the two-column grid rather
   than inside it, so it centres on its own line at every width. */

.video-badge{position:relative;z-index:1;margin-top:clamp(40px,5vw,64px);text-align:center;}

.video-badge h3{font-size:clamp(20px,2.2vw,28px);font-weight:900;letter-spacing:-0.3px;line-height:1.2;margin-bottom:22px;}

.video-badge img{display:block;width:100%;max-width:260px;height:auto;margin:0 auto;}


/* ═══════ LONG-FORM COPY ═══════ */

/* interior.css styles .seo-content headings but never gives an
   ordinary paragraph a bottom margin, and the global reset has
   already taken the browser default away. Every restored page
   carries these two rules for that reason. */

.seo-inner p{font-size:17px;color:var(--muted);line-height:1.8;margin-bottom:16px;}

.seo-inner h4{font-size:18px;font-weight:800;margin:28px 0 10px;color:var(--text);}


/* BULLETED LISTS — long-form and FAQ answers
   The global reset (global.css:274) zeroes list-style and padding on
   every element, so a <ul> in either place renders as unbulleted,
   unindented paragraphs with no gap between them. Measured on
   /beauty-salon-seo/, which is the first page on this template to
   have one: list-style disc but padding-left 0, and margin-bottom 0
   on both the list and every item.

   The dot is a ::before rather than the real marker, the same way
   every other page stylesheet in the theme does it — ::marker takes
   almost no positioning, and this needs to sit on the first line's
   baseline rather than the top of the line box.

   No color rule here. interior.css sets `.seo-content :is(p,li,…)`
   and `.faq :is(p,li,…)` with !important and loads after this file,
   so a color written here would be dead on arrival. The bullet is a
   background, not text, which is why it is allowed one.

   :not([class]) is load-bearing, not tidiness. The first draft of
   this block was a plain `.seo-doc ul` and it swallowed the Other
   Services rail, which is also a <ul> in .seo-doc and has its own
   styling: measured on /ai-optimization-in-philadelphia/, its "›"
   chevrons turned into teal dots, its indent went 18px to 22px, and
   every item in a grid layout picked up a 12px bottom margin. This
   block is for a list that arrives from the editor with no styling
   of its own, and a list with a class is not that. */

.seo-content .seo-doc ul:not([class]),
.faq-a ul:not([class]){list-style:none;padding:0;margin:0 0 16px;}

.seo-content .seo-doc ul:not([class]) li,
.faq-a ul:not([class]) li{position:relative;padding-left:22px;margin-bottom:12px;line-height:1.75;}

.seo-content .seo-doc ul:not([class]) li:last-child,
.faq-a ul:not([class]) li:last-child{margin-bottom:0;}

.seo-content .seo-doc ul:not([class]) li::before,
.faq-a ul:not([class]) li::before{content:'';position:absolute;left:0;top:10px;width:6px;height:6px;border-radius:50%;background:var(--teal-ink);}


/* ═══════ Long-form tables ═══════

   The first table in this theme, and global.css:274 is
   `*{margin:0;padding:0}` — which strips a table down to text stuck
   against text, since every bit of a table's readability is cell
   padding and borders it no longer has. Hence explicit everything.

   The wrapper scrolls rather than the page. Three columns of prose
   will not fit 390px at a readable size, and the house rule is that a
   table gets its own overflow so the page body never scrolls
   sideways — layout-pass.js asserts both halves of that.

   border-collapse so adjacent cells share one rule rather than
   doubling it, and a header that stays put while a wide table is
   scrolled under it. */

.seo-doc .aiopt-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 0 28px;border:1px solid var(--border);border-radius:12px;}

.seo-doc .aiopt-table{border-collapse:collapse;width:100%;min-width:640px;font-size:15px;line-height:1.6;}

.seo-doc .aiopt-table th,
.seo-doc .aiopt-table td{padding:14px 16px;text-align:left;vertical-align:top;border-bottom:1px solid var(--border);}

.seo-doc .aiopt-table thead th{position:sticky;top:0;background:var(--cream);color:var(--ink);font-weight:700;font-size:14px;letter-spacing:0.01em;}

/* The row header carries the component name. Bolder than the cells
   beside it, because it is what somebody scanning the table reads. */
.seo-doc .aiopt-table tbody th{font-weight:650;color:var(--ink);white-space:nowrap;}

.seo-doc .aiopt-table tbody tr:last-child th,
.seo-doc .aiopt-table tbody tr:last-child td{border-bottom:0;}

.seo-doc .aiopt-table tbody tr:nth-child(even){background:rgba(15,23,42,0.02);}


/* ═══════ CTA ═══════ */

.cta{padding:clamp(80px,10vw,120px) 0;position:relative;overflow:hidden;background:linear-gradient(135deg,#0d1f2d,#0a1a26,#0d2535);}

.cta::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 50% 60% at 50% 50%,rgba(22,192,183,0.08) 0%,transparent 60%);}

.cta-inner{position:relative;z-index:1;text-align:center;max-width:720px;margin:0 auto;padding:0 2.5rem;}

.cta h2{font-size:clamp(30px,3.8vw,52px);font-weight:900;letter-spacing:-1px;line-height:1.08;margin-bottom:18px;}

.cta h2 em{font-style:normal;color:var(--teal);}

.cta p{font-size:17px;color:rgba(248,250,252,0.6);line-height:1.7;margin-bottom:36px;max-width:560px;margin-left:auto;margin-right:auto;}

.cta-btns{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;}

/* ═══════ THE PAGE'S OWN CLIENT LOGO WALL ═══════

   Not the marquee strip under the hero, which carries the whole
   roster on every interior page. This is a shortlist a single page
   makes its case with — four law firms on
   /seo-for-criminal-defense-attorneys/ — so it is a static centred
   row rather than a marquee: four items on a track is mostly empty
   track, the same argument client-strip.php makes for itself.

   The logos arrive as supplied artwork at whatever size the client
   sent, so height is what gets normalised and width follows. They
   sit on a light card because most supplied logos are dark-on-white
   and would disappear straight into this template's dark surface. */
.aiopt-logos{padding:clamp(48px,6vw,80px) 0;background:var(--surface);position:relative;z-index:2;}

/* On the dark surface, not the navy ink the cream bands use: that was
   near-invisible. Set like the page's eyebrows, so it reads as a label
   over the logos rather than competing with them. */
.aiopt-logos-h{
  font-family:var(--mono2);font-size:12px;font-weight:700;letter-spacing:0.18em;text-transform:uppercase;
  text-align:center;margin-bottom:clamp(24px,3vw,40px);color:var(--teal);
}

.aiopt-logos-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:clamp(16px,2.4vw,32px);}

.aiopt-logos-list li{flex:0 0 auto;background:#fff;border-radius:12px;padding:18px 24px;display:flex;align-items:center;justify-content:center;min-height:96px;border:1px solid rgba(22,192,183,0.14);}

.aiopt-logos-list img{display:block;height:44px;width:auto;max-width:200px;object-fit:contain;}

.aiopt-logos-list a{display:flex;align-items:center;transition:opacity .2s ease;}

.aiopt-logos-list a:hover{opacity:.72;}

@media(max-width:600px){
  .aiopt-logos-list li{padding:14px 18px;min-height:78px;}
  .aiopt-logos-list img{height:34px;max-width:150px;}
}

/* ── Portfolio band (template-parts/aio-portfolio.php) ──
   The sites built for this industry, three across, each a link to
   the live site. Same surface and radius as the image blocks above. */
/* ── Portfolio band: the work, large, straight under the hero ──
   One site in a wide browser frame beside its words, then the rest
   three across. Every screenshot is cropped to the top of the page
   and scrolls down while the pointer rests on it. */
.aiopt-pf{padding:clamp(56px,7vw,96px) 0;background:var(--obsidian);position:relative;z-index:2;}
.aiopt-pf-head{max-width:720px;margin:0 auto 36px;text-align:center;}
.aiopt-pf-head h2{font-size:clamp(28px,3.4vw,44px);font-weight:900;letter-spacing:-0.5px;line-height:1.1;margin:8px 0 10px;}
.aiopt-pf-head p{color:var(--muted);font-size:16px;line-height:1.7;}
.aiopt-pf-card{
  display:flex;flex-direction:column;
  border-radius:20px;overflow:hidden;text-decoration:none;color:#F8FAFC;
  background:linear-gradient(180deg,rgba(12,26,38,0.7),rgba(5,11,18,0.5));
  border:1px solid rgba(22,192,183,0.14);
  transition:transform .3s ease,border-color .3s ease,box-shadow .3s ease;
}
a.aiopt-pf-card:hover{transform:translateY(-4px);border-color:rgba(22,192,183,0.45);box-shadow:0 30px 70px rgba(0,0,0,0.5),0 0 40px rgba(22,192,183,0.12);}
.aiopt-pf-frame{background:#0c1a26;}
.aiopt-pf-bar{
  display:flex;align-items:center;gap:7px;height:32px;padding:0 14px;
  background:rgba(255,255,255,0.05);border-bottom:1px solid rgba(255,255,255,0.08);
}
.aiopt-pf-bar span{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,0.16);flex-shrink:0;}
.aiopt-pf-bar span:first-child{background:rgba(22,192,183,0.7);}
.aiopt-pf-bar em{
  margin-left:10px;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:var(--mono2);font-style:normal;font-size:11px;letter-spacing:0.04em;color:rgba(248,250,252,0.5);
  padding:3px 10px;border-radius:6px;background:rgba(5,11,18,0.5);
}
.aiopt-pf-shot{aspect-ratio:16/11;overflow:hidden;display:grid;place-items:center;}
.aiopt-pf-shot img{display:block;width:100%;height:100%;object-fit:cover;object-position:top;transition:object-position 7s linear;}
a.aiopt-pf-card:hover .aiopt-pf-shot img{object-position:bottom;}
.aiopt-pf-wordmark{font-family:var(--disp);font-size:22px;color:rgba(223,239,253,0.4);padding:20px;text-align:center;}
.aiopt-pf-body{padding:18px 20px 20px;}
.aiopt-pf-body h3{font-size:18px;font-weight:900;letter-spacing:-0.2px;margin-bottom:6px;}
.aiopt-pf-body p{font-size:14px;line-height:1.6;color:var(--muted);margin-bottom:10px;}
.aiopt-pf-go{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:700;color:var(--teal);}
.aiopt-pf-go i{font-size:11px;transition:transform .2s ease;}
a.aiopt-pf-card:hover .aiopt-pf-go i{transform:translate(2px,-2px);}
/* The lead: frame left at two thirds, the words beside it. */
.aiopt-pf-lead{
  display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);align-items:center;
  margin-bottom:22px;
  border-color:rgba(22,192,183,0.28);
  box-shadow:0 30px 80px rgba(0,0,0,0.45);
}
.aiopt-pf-lead .aiopt-pf-shot{aspect-ratio:16/10;}
.aiopt-pf-lead .aiopt-pf-body{padding:36px 40px;}
.aiopt-pf-lead .aiopt-pf-body h3{font-size:clamp(24px,2.6vw,34px);letter-spacing:-0.5px;margin-bottom:12px;}
.aiopt-pf-lead .aiopt-pf-body p{font-size:16px;line-height:1.7;margin-bottom:18px;}
.aiopt-pf-lead .aiopt-pf-go{
  padding:12px 20px;border-radius:999px;background:var(--teal);color:#052e2c;font-size:14px;
}
.aiopt-pf-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;}
.aiopt-pf-more{margin:26px 0 0;text-align:center;font-size:15px;}
.aiopt-pf-more .t-link i{font-size:12px;margin-left:4px;}
@media (max-width:1100px){.aiopt-pf-grid{grid-template-columns:1fr 1fr;}}
@media (max-width:900px){
  .aiopt-pf-lead{grid-template-columns:1fr;}
  .aiopt-pf-lead .aiopt-pf-body{padding:22px 22px 24px;}
}
@media (max-width:600px){.aiopt-pf-grid{grid-template-columns:1fr;}}
@media (prefers-reduced-motion:reduce){
  .aiopt-pf-shot img{transition:none;}
  a.aiopt-pf-card:hover .aiopt-pf-shot img{object-position:top;}
}
