/* OnSpot Locksmith 24/7 — site stylesheet */
:root{
  --navy:#0d2137;--navy2:#132f4c;--navy3:#1b3a5c;
  --amber:#f6a821;--amber-d:#e09405;
  /* --amber-text is the accent for small text on light backgrounds:
     --amber-d is 2.50:1 on white, below the 4.5:1 WCAG AA needs. */
  --amber-text:#a56600;
  --bg:#f6f8fb;--card:#ffffff;--line:#e3e9f0;
  --text:#22303f;--muted:#5b6b7c;--ok:#1d8a4e;
  --radius:14px;--shadow:0 2px 14px rgba(13,33,55,.08);
  --maxw:1120px;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;color:var(--text);background:var(--bg);line-height:1.65;font-size:16.5px}
img{max-width:100%;height:auto;display:block}
a{color:var(--navy2)}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
h1,h2,h3{color:var(--navy);line-height:1.22;font-weight:800;letter-spacing:-.01em}
h1{font-size:clamp(1.9rem,4.5vw,3rem)}
h2{font-size:clamp(1.45rem,3vw,2.1rem);margin-bottom:14px}
h3{font-size:1.12rem}
.eyebrow{text-transform:uppercase;letter-spacing:.14em;font-size:.78rem;font-weight:700;color:var(--amber-text);margin-bottom:8px}
section{padding:56px 0}
.lead{font-size:1.08rem;color:var(--muted);max-width:62ch}
.center{text-align:center}
.center .lead{margin-inline:auto}

/* Header */
.topbar{background:var(--navy);color:#cfe0f2;font-size:.85rem;padding:6px 0}
.topbar .wrap{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap}
.topbar a{color:#fff;text-decoration:none;font-weight:600}
.topbar b{color:#fff;font-weight:700}
.tb-hours{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tb-shop{background:rgba(255,255,255,.12);border-radius:999px;padding:2px 10px;white-space:nowrap}
.tb-dot{opacity:.5}
header.site{position:sticky;top:0;z-index:50;background:#fff;border-bottom:1px solid var(--line);box-shadow:0 1px 8px rgba(13,33,55,.06)}
.nav{display:flex;align-items:center;gap:18px;min-height:68px}
/* Brand block: OnSpot is the business identity and stays primary. SLO Car &
   Key is the retired trading name still on the vans, so it sits beside it at
   about half the height, behind a divider, reading as a second mark of the
   same company rather than a second company. */
/* flex:none, never min-width:0 - allowing this to shrink below its content
   does not wrap it, it overflows it, and the second mark lands on top of the
   first menu link. */
/* flex-start, so the divider and the second mark are positioned against the
   top of the block (where the 46px OnSpot mark is) rather than against the
   centre of mark-plus-caption. Their margin-top then centres each on the mark
   itself: (46-30)/2 = 8 and (46-34)/2 = 6. */
.brand-group{display:flex;align-items:flex-start;gap:18px;margin-right:auto;flex:0 0 auto}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none}
.brand img{height:46px;width:auto}
/* Block, not a flex column: as a flex item the logo's auto width resolves
   against the container rather than its own aspect ratio, so the narrower
   "Incorporated" line below it squashed the mark from 143px to 93px wide. */
.brand-mark{display:block;text-align:right}
/* max-width:none matters: the global `img{max-width:100%}` resolves against a
   shrink-to-fit container, so the percentage makes the logo's own width count
   as indefinite and the narrower "Incorporated" line below it decides the
   box - squashing the mark from 143px to 93px. Both brand marks opt out. */
.brand-mark img{display:block;max-width:none}
/* One hue in the brand block. The mark, the suffix and the nav links are all
   navy; amber is left to the call button alone, where a warm accent is doing
   a job. Hierarchy here comes from size and opacity, not a second colour -
   an amber suffix beside the blue SLO badge was two accents competing. */
/* Negative margin because the logo's box is taller than its wordmark: the
   door-plate icon runs the full height of the PNG while the text ink stops
   95px short of the bottom, which is 9.4px of dead space at a 46px render.
   margin-top:0 would already leave the caption ~9px adrift. -7px sets it
   about 2px under the words. Safe to overlap upward: the caption is
   right-aligned and the icon it would collide with is at the far left. */
.brand-inc{display:block;font-size:.58rem;line-height:1;letter-spacing:.2em;text-transform:uppercase;font-weight:700;color:var(--navy);opacity:.62;margin-top:-7px;padding-right:2px}
/* Both sit 15px higher than the group's centre so they line up with the
   middle of the OnSpot mark itself, not with the middle of mark-plus-caption.
   Centred on the whole block they sat level with "Incorporated", and the two
   read as one phrase: "Incorporated SLO Car and Key". */
.brand-divider{width:1px;height:34px;background:var(--line);flex:none;margin-top:6px}
/* (46-40)/2 = 3, so the banner centres on the OnSpot mark rather than on
   mark-plus-caption. The artwork is the van wrap: it carries its own dark
   background, so it is rounded to read as a deliberate badge on the white
   header instead of a stray rectangle. */
.brand-alt{display:flex;align-items:center;margin-top:3px}
.brand-alt img{height:40px;width:auto;max-width:none;border-radius:6px;display:block}
.menu{display:flex;gap:2px;align-items:center;list-style:none}
.menu a{display:block;padding:8px 9px;border-radius:8px;text-decoration:none;color:var(--navy);font-weight:600;font-size:.92rem;white-space:nowrap}
.menu a:hover,.menu a[aria-current="page"]{background:#eef3f9;color:var(--navy2)}
.btn{display:inline-block;padding:13px 22px;border-radius:10px;font-weight:800;text-decoration:none;text-align:center;transition:transform .08s ease,background .15s ease;border:2px solid transparent}
.btn:active{transform:scale(.98)}
.btn-call{background:var(--amber);color:var(--navy)!important;box-shadow:0 2px 10px rgba(246,168,33,.4)}
.btn-call:hover{background:var(--amber-d)}
.btn-ghost{border-color:#fff;color:#fff!important}
.btn-ghost:hover{background:rgba(255,255,255,.12)}
.btn-navy{background:var(--navy2);color:#fff!important}
.btn-navy:hover{background:var(--navy3)}
.nav .btn-call{padding:10px 16px;font-size:.95rem;white-space:nowrap}
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--navy);color:#fff;padding:10px 16px;border-radius:0 0 8px 0;font-weight:700;text-decoration:none}
.skip:focus{left:0}
/* Hidden outright while the full menu is on show - there is nothing for it
   to toggle, so it should not be in the tab order either. It becomes
   focusable at the breakpoint where the hamburger appears. */
#menu-toggle{display:none}
.hamburger{display:none;cursor:pointer;padding:10px;border-radius:8px}
.hamburger span{display:block;width:24px;height:3px;background:var(--navy);margin:5px 0;border-radius:2px}

.req{font-weight:600;font-size:.82rem;color:var(--muted)}

/* Hero */
.hero{background:linear-gradient(155deg,var(--navy) 0%,var(--navy2) 55%,#17456e 100%);color:#fff;padding:64px 0 56px}
.hero h1{color:#fff;max-width:21ch}
.hero .sub{color:#d9e6f4;font-size:1.15rem;max-width:56ch;margin:18px 0 26px}
.hero .cta-row{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:30px}
.badges{display:flex;gap:10px;flex-wrap:wrap;list-style:none}
.badges li{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.22);color:#eaf2fb;padding:7px 14px;border-radius:999px;font-size:.86rem;font-weight:600}
.hero-city{padding:56px 0 48px}
.crumbs{font-size:.85rem;margin-bottom:16px;color:#a9c2db}
.crumbs a{color:#d9e6f4}
.crumbs span{color:#f6a821}

/* Cards */
.grid{display:grid;gap:20px}
.grid-2{grid-template-columns:repeat(2,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr)}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:26px;box-shadow:var(--shadow)}
.card .icon{font-size:1.9rem;line-height:1;margin-bottom:12px}
.card h3{margin-bottom:8px}
.card p{color:var(--muted);font-size:.97rem}
.card .more{display:inline-block;margin-top:12px;font-weight:700;text-decoration:none;color:var(--amber-d)}
.svc-list{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-top:26px}
.svc-item{background:#fff;border:1px solid var(--line);border-radius:12px;padding:16px 18px}
.svc-item h3{font-size:1rem;margin-bottom:4px;display:flex;gap:8px;align-items:baseline}
.svc-item h3::before{content:"✓";color:var(--ok);font-weight:800}
.svc-item p{color:var(--muted);font-size:.92rem}

/* Steps */
.steps{counter-reset:s}
.step{counter-increment:s;position:relative;padding-left:0}
.step .num{width:40px;height:40px;border-radius:50%;background:var(--amber);color:var(--navy);font-weight:800;display:flex;align-items:center;justify-content:center;font-size:1.1rem;margin-bottom:12px}

/* Reviews */
.review{display:flex;flex-direction:column}
.stars{color:var(--amber);letter-spacing:2px;margin-bottom:10px;font-size:.95rem}
.review p{flex:1}
.review cite{margin-top:14px;font-style:normal;font-weight:700;color:var(--navy)}
.review cite small{display:block;font-weight:500;color:var(--muted)}

/* Why us */
.why{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;list-style:none;margin-top:20px}
.why li{background:#fff;border:1px solid var(--line);border-radius:12px;padding:14px 18px;font-weight:600;color:var(--navy);display:flex;gap:10px;align-items:center}
.why li::before{content:"★";color:var(--amber)}

/* Areas */
.areas{background:#fff;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.city-links{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;list-style:none;margin-top:22px}
.city-links a{display:block;padding:10px 14px;background:var(--bg);border:1px solid var(--line);border-radius:10px;text-decoration:none;color:var(--navy);font-weight:600;font-size:.93rem}
.city-links a:hover{border-color:var(--amber);background:#fff8ea}
.map-card{margin-top:26px;border-radius:var(--radius);overflow:hidden;border:1px solid var(--line);max-width:680px}

/* FAQ */
.faq details{background:#fff;border:1px solid var(--line);border-radius:12px;margin-bottom:10px;padding:0}
.faq summary{cursor:pointer;font-weight:700;color:var(--navy);padding:16px 20px;list-style:none;position:relative}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";position:absolute;right:18px;top:12px;font-size:1.4rem;color:var(--amber-d)}
.faq details[open] summary::after{content:"–"}
.faq details p{padding:0 20px 16px;color:var(--muted)}

/* CTA band */
.cta-band{background:linear-gradient(120deg,var(--navy2),var(--navy));color:#fff;border-radius:var(--radius);padding:40px;display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap}
.cta-band h2{color:#fff;margin:0}
.cta-band p{color:#d9e6f4}

/* Article / legal */
.article{max-width:760px;margin:0 auto}
.article h2{margin-top:34px}
.article h3{margin-top:22px;margin-bottom:8px}
.article p,.article ul,.article ol{margin-bottom:16px}
.article ul,.article ol{padding-left:24px}
.post-meta{color:var(--muted);font-size:.9rem;margin-bottom:24px}
/* Blog cards sit directly under the page h1, so they are h2 for heading
   order; keep them at the size the h3 rendered. */
.post-card h2{font-size:1.12rem;line-height:1.22;margin-bottom:8px}
.post-card h2 a{text-decoration:none;color:var(--navy)}
.post-card h2 a:hover{color:var(--amber-text)}

/* Forms */
form .row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
label{font-weight:600;font-size:.9rem;color:var(--navy);display:block;margin-bottom:4px}
input,select,textarea{width:100%;padding:12px 14px;border:1px solid var(--line);border-radius:10px;font:inherit;background:#fff;margin-bottom:14px}
input:focus-visible,select:focus,textarea:focus{outline:2px solid currentColor;outline-offset:2px;border-color:var(--amber)}

/* Footer */
footer.site{background:var(--navy);color:#b9cde0;padding:52px 0 90px;font-size:.94rem}
footer.site h3{color:#fff;font-size:1rem;margin-bottom:12px}
footer.site a{color:#dce9f5;text-decoration:none}
footer.site a:hover{color:var(--amber)}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.2fr;gap:32px}
.foot-grid ul{list-style:none}
.foot-grid li{margin-bottom:8px}
.foot-bottom{border-top:1px solid rgba(255,255,255,.14);margin-top:36px;padding-top:20px;display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:.85rem;color:#8fa8c0}

/* Sticky mobile call bar */
.callbar{position:fixed;bottom:0;left:0;right:0;z-index:60;display:none;background:var(--amber);color:var(--navy);text-align:center;padding:14px;font-weight:800;text-decoration:none;font-size:1.05rem;box-shadow:0 -3px 14px rgba(13,33,55,.25)}

/* The header carries more than the body: two brand marks, eight links and the
   call button. It gets a wider wrap than the 1120px content column so the
   second mark does not have to come out of the menu's space.
   The pair below must not leave a gap: a viewport can be a fractional number
   of CSS pixels, and at 1279.5 neither `max-width:1279px` nor
   `min-width:1280px` matched - the menu rendered at full width inside the
   narrow wrap and pushed the call button off the row. Hence the .98. */
@media(min-width:1280px){
  header.site .wrap{max-width:1280px}
}
/* Collapse to the hamburger below 1280 rather than 1160: the row needs about
   1218px for both marks, eight links and the call button, and the overflow is
   silent - the call button slides off the row rather than wrapping. */
@media(max-width:1279.98px){
  .menu{position:absolute;top:100%;left:0;right:0;background:#fff;flex-direction:column;align-items:stretch;padding:10px 16px 16px;border-bottom:1px solid var(--line);display:none;box-shadow:0 12px 20px rgba(13,33,55,.12)}
  #menu-toggle:checked~.menu{display:flex}
  /* Visually hidden but still focusable: display:none would drop it out of
     the tab order and leave the mobile menu unreachable by keyboard, which
     is every navigation link on the site below 1280px. */
  #menu-toggle{display:block;position:absolute;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}
  #menu-toggle:focus-visible+.hamburger{outline:2px solid currentColor;outline-offset:2px}
  .hamburger{display:block}
}
@media(max-width:900px){
  .grid-3,.grid-4{grid-template-columns:repeat(2,1fr)}
  .foot-grid{grid-template-columns:1fr 1fr}
  .city-links{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:640px){
  section{padding:40px 0}
  .grid-2,.grid-3,.grid-4,.svc-list,.why,form .row{grid-template-columns:1fr}
  .city-links{grid-template-columns:repeat(2,1fr)}
  .foot-grid{grid-template-columns:1fr}
  .callbar{display:block}
  /* Keep the topbar on phones, but drop the street address and the phone
     link: the sticky header and the fixed call bar both already carry the
     number. What survives is the hours, which exist nowhere else. */
  .topbar .wrap{justify-content:center;gap:8px;text-align:center}
  .tb-addr,.tb-tel{display:none}
  .tb-hours{justify-content:center;font-size:.8rem}
  /* Phone headers are tight: the OnSpot logo, the call button and the
     hamburger already fill the row, so the secondary mark steps aside rather
     than pushing the call button off. */
  .brand-divider,.brand-alt{display:none}
  /* The mark now keeps its true 3.12:1 ratio instead of being squeezed by
     `img{max-width:100%}`, so it has to get shorter rather than narrower to
     leave the hamburger and the call button their room. */
  .nav{gap:10px}
  .brand img{height:36px}
  /* Dead space under the wordmark scales with the mark: 7.4px at 36px tall. */
  .brand-inc{margin-top:-5px}
  .nav .btn-call{padding:9px 13px;font-size:.85rem}
  .brand b{font-size:.92rem}
  .brand small{font-size:.6rem}
  .cta-band{padding:28px}
}

/* Some people get motion sickness from smooth scrolling and moving UI. The OS
   setting is the signal; honour it rather than overriding their choice. */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* --- pricing table -------------------------------------------------------
   Three columns on desktop; on narrow screens the wrapper scrolls rather
   than the page, so the body never scrolls sideways. The "what changes it"
   column is not decoration - a bare from-price reads as a final price, and
   the note beside it is what keeps the floor honest. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* The service call, stated once. It is the single number that applies to
   every row, so it gets its own block rather than thirteen repetitions. */
.pricing-callout{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--amber);border-radius:var(--radius);padding:22px 26px;box-shadow:var(--shadow)}
.pricing-callout h2{margin:0 0 10px;font-size:1.35rem}
.pricing-callout p{color:var(--muted);max-width:75ch;margin-bottom:0}
.pricing-callout p+p{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.pricing-callout .shop-note{font-size:.95rem}
table.pricing{width:100%;border-collapse:collapse;margin-top:22px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
table.pricing th,table.pricing td{padding:14px 16px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}
table.pricing thead th{background:var(--bg);font-size:.85rem;letter-spacing:.02em;text-transform:uppercase;color:var(--muted)}
table.pricing tbody tr:last-child th,table.pricing tbody tr:last-child td{border-bottom:0}
table.pricing tbody th{font-weight:700;color:var(--text)}
table.pricing .price{font-weight:700;color:var(--muted);white-space:nowrap}
/* The typical range is the number most people will pay, so it carries the
   emphasis. Styling the floor louder would undo the point of showing both. */
table.pricing .typical{font-weight:800;color:var(--amber-text);white-space:nowrap}
table.pricing .moves{color:var(--muted);font-size:.93rem}
@media(max-width:640px){
  table.pricing th,table.pricing td{padding:11px 12px}
  table.pricing .moves{font-size:.88rem}
  /* Four columns will not fit a phone. The wrapper scrolls, so set a floor
     wide enough that the two price columns stay side by side and comparable
     - they only do their job when read together. */
  table.pricing{min-width:34rem}
}
