/* Executive PC Services: the site's one stylesheet.
   The sections below follow the page from top to bottom. Every colour is a custom property in the :root
   block below, named for the job it does, so another look can change the whole page in one place: the block
   after it gives the same properties the dark look's values.
   The rules for narrower screens come at the end, at three breakpoints: 960px, 720px and 560px. The one exception
   is the menu bar's own, at 1099px, up to which its links take a row of their own (see "Tablets and phones"). */

/* ---------- Font ---------- */
@font-face {
  font-family: Figtree;
  src: url(/fonts/figtree-latin.woff2) format("woff2");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- Colours, type and widths ---------- */
:root {
  color-scheme: light;                /* the browser's own parts, such as scroll bars, drawn light; the dark look sets dark */
  --font: Figtree, system-ui, sans-serif;
  --content-width: 1160px;            /* the widest the content gets */
  --gutter: 44px;                     /* the least room beside the content */
  --call-bar-height: 56px;            /* the call bar on phones, and the room kept for it at the foot of the page */

  /* Colours used across the page */
  --page-edge: #fff;                  /* behind the page, seen past its top and bottom */
  --page-bg: #fff;                    /* the page, and the sections that are white */
  --raised-bg: #f3f6fc;               /* the tinted section (Why us) */
  --card-bg: #fff;                    /* cards, city names, the "since 2001" pill, the See services button */
  --line: #e3e8f2;                    /* card edges and other outlines */
  --line-soft: #dfe6f3;               /* dividers between the Why us points */
  --text: #0b1b33;                    /* headings and body text */
  --text-secondary: #33435e;          /* the pill, the rating line, city names */
  --text-muted: #51607a;              /* descriptions and small print */
  --accent: #1d5cff;                  /* small blue text and icons: section labels, icon tiles, the reviews link */
  --headline-accent: #1d5cff;         /* "the geek speak." */
  --icon-tile-bg: #e7eeff;            /* the square behind each small blue icon */
  --action: #1d5cff;                  /* blue buttons and the 25+ badge */
  --action-hover: #3a72ff;            /* a blue button under the pointer */
  --on-action: #fff;                  /* text on blue buttons and the 25+ badge */
  --star: #f5a623;                    /* rating stars */
  --focus-ring: #1d5cff;              /* keyboard focus on the page */
  --focus-ring-on-band: #fff;         /* keyboard focus on the navy and blue bands and the footer */

  /* Top bar */
  --top-bar-bg: #0b1b33;
  --top-bar-text: #c5d1e8;
  --top-bar-edge: none;               /* a hairline under the bar, as a box-shadow */
  /* The "Open now" sign in the top bar, the same in both looks. Its green is the only green on the page. */
  --open-now-dot: #1fc98a;
  --open-now-ring: 0 0 0 3px rgba(31, 201, 138, .2);   /* a soft ring round the dot, as a box-shadow */
  --open-now-text: #fff;
  --open-now-divider: rgba(255, 255, 255, .22);        /* the hairline between the sign and the hours */

  /* Menu bar */
  --logo-mark: #1d5cff;
  --logo-text: #0b1b33;
  --menu-link: #51607a;
  --menu-phone-bg: #0b1b33;
  --menu-phone-text: #fff;
  --menu-phone-icon: #fff;
  --switch-line: #e3e8f2;             /* the light and dark switch: its edge */
  --switch-icon: #51607a;             /* the icon in a button that is not pressed */
  --switch-hover-bg: #f3f6fc;         /* a button under the pointer */
  --switch-hover-icon: #0b1b33;
  --switch-pressed-bg: #e7eeff;       /* the pressed button */
  --switch-pressed-icon: #1d5cff;

  /* Top section */
  --top-section-bg: linear-gradient(180deg, #fff 0%, #f2f6fd 100%);
  --pill-shadow: 0 4px 12px rgba(11, 27, 51, .06);
  --primary-button-shadow: 0 10px 22px rgba(29, 92, 255, .3);
  --secondary-button-line: #dbe2ee;
  --photo-filter: none;               /* applied to all three photos */
  --photo-large-shadow: 0 30px 60px rgba(11, 27, 51, .18);
  --photo-small-frame: #fff;
  --photo-small-shadow: 0 22px 44px rgba(11, 27, 51, .22);
  --badge-bg: #fff;                   /* the two badges on the photos */
  --badge-line: #e3e8f2;
  --badge-shadow: 0 14px 34px rgba(11, 27, 51, .18);
  --award-tile-bg: #fff3d6;           /* the CompTIA badge's icon */
  --award-tile-icon: #b7791f;

  /* Call-back band and its form */
  --callback-bg: linear-gradient(120deg, #0b1b33 0%, #14346a 100%);
  --callback-edge: none;              /* hairlines above and below the band, as a box-shadow */
  --callback-heading: #fff;           /* the heading, the phone numbers and the confirmation */
  --callback-text: #c3cee3;
  --field-label: #c3cee3;
  --field-bg: #fff;
  --field-text: #0b1b33;
  --field-edge: none;                 /* a ring round each field, as a box-shadow */
  --field-focus-ring: #6ea8ff;
  --field-invalid-ring: #d92d20;      /* the ring inside a field the server refused: 4.8:1 against the white field */
  --form-error-text: #ffb4ab;         /* the failure message and the line under a refused field: 5.4:1 or more on the band in either look */
  --submit-shadow: 0 10px 24px rgba(29, 92, 255, .45);

  /* Services: the Managed IT card */
  --featured-card-bg: linear-gradient(160deg, #0b1b33, #14346a);
  --featured-card-line: transparent;
  --featured-card-title: #fff;
  --featured-card-text: #b9c6de;
  --featured-tile-bg: rgba(255, 255, 255, .12);
  --featured-tile-icon: #8fc0ff;

  /* Why us */
  --why-photo-shadow: 0 26px 56px rgba(11, 27, 51, .18);
  --years-badge-shadow: 0 18px 40px rgba(29, 92, 255, .4);

  /* How it works */
  --step-number-bg: #0b1b33;
  --step-number-text: #fff;

  /* Reviews */
  --quote-bg: #f3f6fc;

  /* Service area */
  --more-cities-bg: #e7eeff;
  --more-cities-line: transparent;
  --more-cities-text: #1d4fd8;

  /* Call band */
  --call-band-bg: linear-gradient(120deg, #1d5cff, #0d3fd0);
  --call-band-text: #fff;
  --call-band-ring: rgba(255, 255, 255, .07);   /* the large faint circle */
  --call-band-button-bg: #fff;
  --call-band-button-text: #0d3fd0;
  --call-band-outline: rgba(255, 255, 255, .45);

  /* Footer */
  --footer-bg: #0b1b33;
  --footer-edge: none;                /* a hairline along the top, as a box-shadow */
  --footer-text: #b9c6de;
  --footer-heading: #fff;             /* the logo, the headings and the phone number */
  --footer-legal: #8494b3;
  --footer-line: rgba(255, 255, 255, .1);
  /* The footer's copy of the switch, on phones. The footer is navy in both looks, so it has the dark look's switch. */
  --footer-switch-line: #24406c;
  --footer-switch-icon: #a7b6d0;
  --footer-switch-hover-bg: rgba(255, 255, 255, .07);
  --footer-switch-hover-icon: #fff;
  --footer-switch-pressed-bg: rgba(93, 145, 255, .2);
  --footer-switch-pressed-icon: #86b0ff;

  /* Call bar (phones) */
  --call-bar-shadow: 0 -8px 24px rgba(11, 27, 51, .14);
}

/* ---------- The dark look ---------- */
/* theme.js sets data-theme="dark" on the root for the dark look, and this block gives the properties above their dark
   values, from themes-reference.md beside the mockup. A property it leaves out is the same in both looks. Without
   JavaScript there is no data-theme, so the page is light. Nothing fades from one look to the other. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --page-edge: #060d19;
  --page-bg: #09162a;
  --raised-bg: #0d1f3b;
  --card-bg: #102646;
  --line: #24406c;
  --line-soft: #1c3359;
  --text: #f3f6fd;
  --text-secondary: #d5deee;
  --text-muted: #a7b6d0;
  --accent: #86b0ff;
  --headline-accent: #5d91ff;
  --icon-tile-bg: rgba(93, 145, 255, .16);
  --focus-ring: #86b0ff;

  --top-bar-bg: #060d19;
  --top-bar-text: #b9c6de;
  --top-bar-edge: inset 0 -1px 0 rgba(255, 255, 255, .08);

  --logo-mark: #86b0ff;
  --logo-text: #fff;
  --menu-link: #b6c3da;
  --menu-phone-bg: #eef3fc;
  --menu-phone-text: #0b1b33;
  --menu-phone-icon: #1d5cff;
  --switch-line: #24406c;
  --switch-icon: #a7b6d0;
  --switch-hover-bg: rgba(255, 255, 255, .07);
  --switch-hover-icon: #fff;
  --switch-pressed-bg: rgba(93, 145, 255, .2);
  --switch-pressed-icon: #86b0ff;

  --top-section-bg: linear-gradient(180deg, #09162a 0%, #0d1f3b 100%);
  --pill-shadow: 0 4px 12px rgba(0, 0, 0, .25);
  --primary-button-shadow: 0 10px 26px rgba(29, 92, 255, .42);
  --secondary-button-line: #2f4c7d;
  --photo-filter: brightness(.9);
  --photo-large-shadow: 0 30px 60px rgba(0, 0, 0, .45);
  --photo-small-frame: #0c1c36;
  --photo-small-shadow: 0 22px 44px rgba(0, 0, 0, .45);
  --badge-bg: #152d52;
  --badge-line: #2d4878;
  --badge-shadow: 0 14px 34px rgba(0, 0, 0, .45);
  --award-tile-bg: rgba(245, 166, 35, .18);
  --award-tile-icon: #f7bd55;

  --callback-bg: linear-gradient(120deg, #122b55 0%, #1b448f 100%);
  --callback-edge: inset 0 1px 0 rgba(255, 255, 255, .08), inset 0 -1px 0 rgba(255, 255, 255, .06);
  --callback-text: #cdd8ec;
  --field-label: #d5deee;
  --field-bg: #0a1930;
  --field-text: #f3f6fd;
  --field-edge: inset 0 0 0 1.5px #4d72b8;
  --field-invalid-ring: #ff8a80;      /* not in the reference: a lighter red, for the dark field */

  --featured-card-bg: linear-gradient(160deg, #1d4fb8 0%, #15367a 100%);
  --featured-card-line: #3f6fdc;
  --featured-card-text: #d8e3f8;
  --featured-tile-bg: rgba(255, 255, 255, .16);
  --featured-tile-icon: #e3ecff;

  --why-photo-shadow: 0 26px 56px rgba(0, 0, 0, .45);

  --step-number-bg: #eef3fc;
  --step-number-text: #0b1b33;

  --quote-bg: #102646;

  --more-cities-bg: rgba(93, 145, 255, .2);
  --more-cities-text: #a3c3ff;

  --footer-bg: #060d19;
  --footer-edge: inset 0 1px 0 rgba(255, 255, 255, .08);

  --call-bar-shadow: 0 -8px 24px rgba(0, 0, 0, .45);   /* not in the reference: the dark look's shadow colour */
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* An iPhone held sideways would enlarge text it judges too small; the sizes here are meant at every width. */
html { background: var(--page-edge); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { margin: 0; background: var(--page-bg); color: var(--text); font-family: var(--font); line-height: 1.5; }
/* On a page shorter than the window, main takes the room left over, so the footer ends at the foot of the window. */
body { display: flex; flex-direction: column; min-height: 100vh; }
main { flex-grow: 1; }
h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
/* Headings that wrap share their words out evenly, so none leaves a word alone on its last line. */
h1, h2, h3 { font-size: inherit; font-weight: inherit; text-wrap: balance; }
ul, ol { padding: 0; list-style: none; }
img, svg, picture { display: block; }
a { color: inherit; text-decoration: none; }
button, input, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* The content column: centred, never wider than --content-width, never closer than --gutter to the edge. */
.container { width: min(var(--content-width), 100% - 2 * var(--gutter)); margin-inline: auto; }

.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.skip-link { position: absolute; top: -100px; left: 16px; z-index: 10; padding: 10px 16px; border-radius: 10px; background: var(--text); color: var(--page-bg); font-size: 14px; font-weight: 700; }
.skip-link:focus { top: 16px; }

/* Keeps a short phrase, such as the place name in running text, on one line. */
.nowrap { white-space: nowrap; }

/* ---------- Shared pieces: icons, buttons, icon tiles, stars, section headings ---------- */
.icon { flex-shrink: 0; width: 18px; height: 18px; }

.button { display: inline-flex; align-items: center; gap: 9px; padding: 14px 22px; border-radius: 12px; font-size: 15px; font-weight: 700; white-space: nowrap; }
.button .icon { width: 16px; height: 16px; }
.button-primary { background: var(--action); box-shadow: var(--primary-button-shadow); color: var(--on-action); }
.button-primary:hover { background: var(--action-hover); }
.button-secondary { border: 1.5px solid var(--secondary-button-line); background: var(--card-bg); color: var(--text); }

.icon-tile { display: grid; flex-shrink: 0; place-items: center; width: 40px; height: 40px; border-radius: 11px; background: var(--icon-tile-bg); color: var(--accent); }
.icon-tile .icon { width: 20px; height: 20px; }

.stars { display: flex; gap: 2px; color: var(--star); }
.stars .icon { width: 16px; height: 16px; }

.section-label { margin-bottom: 8px; color: var(--accent); font-size: 12.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.section-title { margin-bottom: 10px; font-size: 31px; font-weight: 800; line-height: 1.15; letter-spacing: -.022em; }
.section-intro { color: var(--text-muted); font-size: 16px; font-weight: 500; }

/* ---------- Top bar ---------- */
.top-bar { background: var(--top-bar-bg); box-shadow: var(--top-bar-edge); color: var(--top-bar-text); font-size: 12.5px; font-weight: 600; }
.top-bar-row { display: flex; justify-content: space-between; padding-block: 9px; }
.top-bar-area, .top-bar-hours { display: flex; align-items: center; }
.top-bar-area { gap: 7px; }
.top-bar .icon { width: 14px; height: 14px; }
/* The "Open now" sign, just before the hours: a green dot, 7px to the words, 12px to a hairline, then 12px to the
   hours. The page carries it hidden and open-now.js shows it during opening hours, so without JavaScript there is no
   sign. Hidden, it takes no room; shown, it takes room to the left of the hours, which end the row and do not move. */
.top-bar-hours { gap: 12px; }
.open-now { display: flex; align-items: center; color: var(--open-now-text); font-weight: 700; }
.open-now[hidden] { display: none; }
.open-now::before { content: ""; flex-shrink: 0; width: 7px; height: 7px; margin-right: 7px; border-radius: 50%; background: var(--open-now-dot); box-shadow: var(--open-now-ring); }
.open-now::after { content: ""; flex-shrink: 0; width: 1px; height: 12px; margin-left: 12px; background: var(--open-now-divider); }

/* ---------- Menu bar ---------- */
.menu-bar { display: flex; align-items: center; justify-content: space-between; padding-block: 10px 8px; }
/* 46px is the height of the mark's box in the approved mockup. The redrawn mark is 47.1px tall at 58px wide,
   so it overhangs this box by half a pixel above and below, and nothing around it moves. */
.logo { display: flex; align-items: center; gap: 12px; height: 46px; }
.logo-mark { width: 58px; height: auto; color: var(--logo-mark); }
.logo-name { color: var(--logo-text); font-size: 25px; font-weight: 600; line-height: 1; white-space: nowrap; }
.menu-links { display: flex; gap: 28px; color: var(--menu-link); font-size: 14px; font-weight: 600; }
.menu-links a { display: block; }
.menu-links a:hover { color: var(--text); }
.menu-actions { display: flex; align-items: center; gap: 14px; }
.menu-phone { display: flex; align-items: center; gap: 8px; padding: 10px 18px; border-radius: 999px; background: var(--menu-phone-bg); color: var(--menu-phone-text); font-size: 14px; font-weight: 700; white-space: nowrap; }
.menu-phone .icon { width: 15px; height: 15px; color: var(--menu-phone-icon); }

/* The light and dark switch: three round buttons in a pill, the pressed one tinted. The page carries it in the menu bar
   and in the footer. The menu bar's copy shows from 721px, beside the phone button; the footer's at 720px and below
   (see "720px and below"). Neither shows while the root has no data-theme. theme.js sets one in the head, before the
   page is first drawn, so the switch is in its place from the first paint, and a page without JavaScript has none. The
   rule that hides it is more specific than every rule that shows a copy, so it wins wherever they sit in this file. */
.theme-switch { display: flex; align-items: center; gap: 2px; width: fit-content; padding: 3px; border: 1px solid var(--switch-line); border-radius: 999px; }
:root:not([data-theme]) .theme-switch { display: none; }
.theme-switch button { display: grid; place-items: center; width: 28px; height: 28px; margin: 0; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--switch-icon); cursor: pointer; -webkit-appearance: none; appearance: none; }
.theme-switch .icon { width: 15px; height: 15px; }
.theme-switch button:hover { background: var(--switch-hover-bg); color: var(--switch-hover-icon); }
.theme-switch button[aria-pressed="true"] { background: var(--switch-pressed-bg); color: var(--switch-pressed-icon); }

/* ---------- Top section ---------- */
.hero { background: var(--top-section-bg); }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr); gap: 40px; align-items: center; padding-block: 40px 64px; }
.hero-pill { width: fit-content; margin-bottom: 18px; padding: 7px 15px; border: 1px solid var(--line); border-radius: 999px; background: var(--card-bg); box-shadow: var(--pill-shadow); color: var(--text-secondary); font-size: 12.5px; font-weight: 700; }
/* The headline is 60px wherever its longer line fits the text column, and smaller where it does not (961px to 1063px).
   "IT support without" is 8.3172em wide and starts 3px left of the column, so it fits while 8.3172 x size <= column + 3px.
   A browser without container query units (Safari 15) drops the min() and keeps the 60px before it. */
.hero-text { container-type: inline-size; }
.hero-title { margin: 0 0 20px -3px; font-size: 60px; font-size: min(60px, (100cqw + 3px) / 8.3172); font-weight: 800; line-height: 1.05; letter-spacing: -.022em; white-space: nowrap; }
.hero-title-accent { color: var(--headline-accent); }
.hero-lead { max-width: 500px; margin-bottom: 22px; color: var(--text-muted); font-size: 17px; font-weight: 500; line-height: 1.6; }
.hero-actions { display: flex; gap: 12px; margin-bottom: 18px; }
.hero-rating { display: flex; align-items: center; gap: 10px; color: var(--text-secondary); font-size: 13.5px; font-weight: 700; }

.hero-photos { position: relative; height: 352px; }
.hero-photo-large, .hero-photo-small { position: absolute; object-fit: cover; filter: var(--photo-filter); }
.hero-photo-large { top: 0; right: 0; width: 88%; height: 298px; border-radius: 26px; box-shadow: var(--photo-large-shadow); }
.hero-photo-small { bottom: 0; left: 0; width: 45%; height: 150px; border: 6px solid var(--photo-small-frame); border-radius: 22px; box-shadow: var(--photo-small-shadow); }
.badge { position: absolute; display: flex; align-items: center; gap: 10px; padding: 10px 14px 10px 10px; border: 1px solid var(--badge-line); border-radius: 14px; background: var(--badge-bg); box-shadow: var(--badge-shadow); }
.badge .icon-tile { width: 34px; height: 34px; border-radius: 10px; }
.badge-title { font-size: 13.5px; font-weight: 700; line-height: 1.3; }
.badge-text { color: var(--text-muted); font-size: 12px; font-weight: 500; }
.badge-onsite { top: 22px; left: 34px; }
.badge-certified { right: -10px; bottom: 38px; }
.icon-tile-award { background: var(--award-tile-bg); color: var(--award-tile-icon); }

/* ---------- Call-back band ---------- */
.callback-band { background: var(--callback-bg); box-shadow: var(--callback-edge); color: var(--callback-heading); }
.callback-band :focus-visible { outline-color: var(--focus-ring-on-band); }
.callback-grid { display: grid; grid-template-columns: minmax(0, .78fr) minmax(0, 1.22fr); gap: 64px; align-items: center; padding-block: 40px 44px; }
.callback-title { margin-bottom: 8px; font-size: 31px; font-weight: 800; line-height: 1.15; letter-spacing: -.022em; }
.callback-intro p { color: var(--callback-text); font-size: 16.5px; font-weight: 500; }
.callback-or { margin-top: 16px; }
.callback-or a { margin-left: 6px; color: var(--callback-heading); font-size: 21px; font-weight: 800; white-space: nowrap; }

.callback-fields { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px 14px; }
.field label { display: block; margin-bottom: 5px; color: var(--field-label); font-size: 12.5px; font-weight: 700; }
.field input, .field textarea { display: block; width: 100%; padding: 12px 13px; border: 0; border-radius: 10px; background: var(--field-bg); box-shadow: var(--field-edge); color: var(--field-text); font: 500 15px/1.4 var(--font); }
.field textarea { height: 62px; padding-top: 10px; resize: vertical; }
.field input:focus, .field textarea:focus { outline: 3px solid var(--field-focus-ring); outline-offset: 1px; }
.field-row { display: flex; grid-column: 1 / -1; align-items: flex-end; gap: 14px; }
.field-message { flex: 1; min-width: 0; }
.callback-submit { height: 62px; padding: 0 22px; border: 0; border-radius: 10px; background: var(--action); box-shadow: var(--submit-shadow); color: var(--on-action); font: 700 15px var(--font); white-space: nowrap; cursor: pointer; }
.callback-submit:hover { background: var(--action-hover); }
/* While a request is under way the button cannot be pressed and reads "Sending…", laid over its resting label, which
   stays in it, hidden, so the button keeps its width and the text box beside it does not move. */
.callback-submit:disabled { position: relative; background: var(--action); cursor: progress; }
.callback-submit-resting { visibility: hidden; }
.callback-submit-sending { position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: flex; align-items: center; justify-content: center; }
/* The trap field for bots: off the screen, and hidden from screen readers by aria-hidden in the page. */
.form-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.form-noscript { margin-top: 14px; color: var(--callback-text); font-size: 14px; font-weight: 500; }
.form-noscript a { color: var(--callback-heading); font-weight: 700; text-decoration: underline; }

/* What /js/callback-form.js shows. A field the server refused gets a ring and a line under it. Turnstile's slot takes
   no room until a challenge shows in it, and then keeps a gap above it. The status line is empty, and takes no room,
   until it holds the failure message under the form or the confirmation in place of the fields. */
.field [aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--field-invalid-ring); }
.field-error { margin-top: 6px; color: var(--form-error-text); font-size: 13.5px; font-weight: 600; line-height: 1.35; }
.cf-turnstile-slot-shown { margin-top: 14px; }
/* The browser tells Cloudflare's frame the look of its place in the page. Without this the slot would pass on the
   root's, the look the visitor picked on the switch, which the privacy page says is sent nowhere; light dark tells the
   frame the device's own setting, which Turnstile's default look follows. */
.cf-turnstile-slot { color-scheme: light dark; }
.form-status-failed { margin-top: 14px; color: var(--form-error-text); font-size: 15px; font-weight: 600; }
.form-status-failed a { color: var(--callback-heading); font-weight: 800; text-decoration: underline; white-space: nowrap; }
.form-status-sent { color: var(--callback-heading); font-size: 21px; font-weight: 800; line-height: 1.3; }
/* Windows contrast themes (forced colours) drop the fields' and the button's backgrounds and the shadows round them,
   and these have no border, so only the labels and the button's words would show. There each gets a 1px border, in
   the colour the theme gives its text. */
@media (forced-colors: active) {
  .field input, .field textarea, .callback-submit { border: 1px solid; }
}

/* ---------- Services ---------- */
.services { padding-block: 60px 56px; text-align: center; }
.services .section-intro { margin-bottom: 28px; }
.service-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; text-align: left; }
.service { padding: 18px; border: 1px solid var(--line); border-radius: 16px; background: var(--card-bg); }
.service .icon-tile { margin-bottom: 13px; }
.service h3 { margin-bottom: 4px; font-size: 15.5px; font-weight: 700; }
.service p { color: var(--text-muted); font-size: 13.5px; font-weight: 500; }
.service-featured { border-color: var(--featured-card-line); background: var(--featured-card-bg); color: var(--featured-card-title); }
.service-featured .icon-tile { background: var(--featured-tile-bg); color: var(--featured-tile-icon); }
.service-featured p { color: var(--featured-card-text); }

/* ---------- Why us ---------- */
.why { background: var(--raised-bg); }
.why-grid { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 56px; align-items: center; padding-block: 56px; }
.why-photo { position: relative; }
.why-photo img { width: 100%; height: 420px; border-radius: 26px; box-shadow: var(--why-photo-shadow); object-fit: cover; object-position: 66% center; filter: var(--photo-filter); }
.years-badge { position: absolute; right: -22px; bottom: 30px; padding: 16px 20px; border-radius: 18px; background: var(--action); box-shadow: var(--years-badge-shadow); color: var(--on-action); }
.years-number { display: block; font-size: 30px; font-weight: 800; line-height: 1.1; letter-spacing: -.02em; }
.years-text { display: block; font-size: 12.5px; font-weight: 600; opacity: .9; }
.why .section-intro { max-width: 480px; margin-bottom: 22px; }
.reason { display: flex; align-items: flex-start; gap: 14px; padding-block: 12px; border-top: 1px solid var(--line-soft); }
.reason h3 { font-size: 15.5px; font-weight: 700; line-height: 1.35; }
.reason p { color: var(--text-muted); font-size: 13.5px; font-weight: 500; }

/* ---------- How it works ---------- */
.how { padding-block: 56px; text-align: center; }
.how .section-title { margin-bottom: 30px; }
.step-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; text-align: left; }
.step { padding: 22px; border: 1px solid var(--line); border-radius: 18px; background: var(--card-bg); }
.step-number { display: grid; place-items: center; width: 38px; height: 38px; margin-bottom: 14px; border-radius: 50%; background: var(--step-number-bg); color: var(--step-number-text); font-size: 15px; font-weight: 800; }
.step h3 { margin-bottom: 4px; font-size: 17px; font-weight: 700; }
.step p { color: var(--text-muted); font-size: 14px; font-weight: 500; }

/* ---------- Reviews ---------- */
.reviews { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, .65fr); gap: 16px; padding-bottom: 56px; }
.review-quote { padding: 30px 32px; border-radius: 22px; background: var(--quote-bg); }
.review-quote .stars { margin-bottom: 14px; }
.review-quote .stars .icon { width: 19px; height: 19px; }
.review-quote blockquote p { margin-bottom: 14px; font-size: 21px; font-weight: 700; line-height: 1.42; letter-spacing: -.01em; }
.review-quote figcaption { color: var(--text-muted); font-size: 13.5px; font-weight: 600; }
.rating-box { display: flex; flex-direction: column; justify-content: center; padding: 30px 28px; border: 1px solid var(--line); border-radius: 22px; }
.rating-score { margin-bottom: 8px; font-size: 44px; font-weight: 800; line-height: 1; letter-spacing: -.03em; }
.rating-box .stars { margin-bottom: 10px; }
.rating-box .stars .icon { width: 20px; height: 20px; }
.rating-count { color: var(--text-muted); font-size: 13.5px; font-weight: 600; }
.rating-link { align-self: flex-start; margin-top: 12px; color: var(--accent); font-size: 14px; font-weight: 700; }
.rating-link:hover { text-decoration: underline; }

/* ---------- Service area ---------- */
.area { padding-bottom: 56px; text-align: center; }
.area .section-intro { margin-bottom: 20px; }
.city-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 9px; }
.city-list li { padding: 8px 15px; border: 1px solid var(--line); border-radius: 999px; background: var(--card-bg); color: var(--text-secondary); font-size: 13.5px; font-weight: 600; }
.city-list .more-cities { border-color: var(--more-cities-line); background: var(--more-cities-bg); color: var(--more-cities-text); }

/* ---------- Call band ---------- */
.call-band { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 48px; padding: 32px 40px; overflow: hidden; border-radius: 24px; background: var(--call-band-bg); color: var(--call-band-text); }
/* The faint circle is 492px across, border included: the mockup draws a 400px box plus its 46px border. */
.call-band::after { content: ""; position: absolute; top: -150px; right: -90px; width: 492px; height: 492px; border: 46px solid var(--call-band-ring); border-radius: 50%; }
.call-band :focus-visible { outline-color: var(--focus-ring-on-band); }
.call-band-copy, .call-band-actions { position: relative; z-index: 1; }
.call-band-title { font-size: 26px; font-weight: 800; line-height: 1.2; letter-spacing: -.02em; }
/* .89 is the least opacity that gives 4.5:1 contrast along the whole line; the mockup's .86 gave about 4.3:1 at its left end. */
.call-band-text { margin-top: 4px; font-size: 15px; font-weight: 500; opacity: .89; }
.call-band-actions { display: flex; gap: 10px; }
.button-light { background: var(--call-band-button-bg); color: var(--call-band-button-text); }
.button-outline { border: 1.5px solid var(--call-band-outline); }

/* ---------- Privacy and not-found pages ---------- */
/* Their main holds a heading, a line under it, and on the privacy page short sections of text. The text runs in a
   column that starts at the header's content edge and is 560px wide, about 65 characters of its 17px text. The line
   under the heading is 18px, so the privacy page's line fits the column with about 34px to spare. */
.text-page { padding-block: 56px 72px; }
.text-page h1, .text-page h2, .text-page p { max-width: 560px; }
.text-page h1 { margin-bottom: 14px; font-size: 44px; font-weight: 800; line-height: 1.1; letter-spacing: -.022em; }
.text-page h2 { margin: 36px 0 8px; font-size: 21px; font-weight: 800; line-height: 1.25; letter-spacing: -.012em; }
.text-page p { color: var(--text-secondary); font-size: 17px; font-weight: 500; line-height: 1.65; }
.text-page .text-page-lead { color: var(--text-muted); font-size: 18px; line-height: 1.55; }
.text-page p a { color: var(--accent); font-weight: 700; text-decoration: underline; text-underline-offset: .15em; }
.text-page a[href^="tel:"] { white-space: nowrap; }
.text-page .text-page-updated { margin-top: 40px; color: var(--text-muted); font-size: 13.5px; font-weight: 600; }
.text-page-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ---------- Footer ---------- */
.site-footer { padding-block: 40px 26px; background: var(--footer-bg); box-shadow: var(--footer-edge); color: var(--footer-text); }
.site-footer :focus-visible { outline-color: var(--focus-ring-on-band); }
/* The first column is never narrower than the logo, whose name does not wrap: 1.5fr is narrower than that from 961px to about 1200px. */
.footer-grid { display: grid; grid-template-columns: minmax(min-content, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr); gap: 32px; padding-bottom: 28px; border-bottom: 1px solid var(--footer-line); }
.site-footer .logo { width: fit-content; margin-bottom: 14px; }
.site-footer .logo-mark, .site-footer .logo-name { color: var(--footer-heading); }
/* 280px, though the line would fit 300px: there the first line misses taking "Dallas–" by only 2.2px, so a browser that
   draws the words a little narrower could split the place name after its dash. At 280px it misses by about 22px, and
   the line breaks where it did at 300px. */
.footer-about { max-width: 280px; font-size: 13.5px; line-height: 1.6; }
.footer-heading { margin-bottom: 12px; color: var(--footer-heading); font-size: 12.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.footer-links li { padding-block: 3px; font-size: 13.5px; font-weight: 500; }
.footer-links .footer-phone { padding-bottom: 6px; color: var(--footer-heading); font-size: 19px; font-weight: 800; white-space: nowrap; }
.footer-links a:hover, .legal a:hover { color: var(--footer-heading); }
/* The footer's copy of the switch, under the logo and its line, is shown at 720px and below only. */
.site-footer .theme-switch { --switch-line: var(--footer-switch-line); --switch-icon: var(--footer-switch-icon); --switch-hover-bg: var(--footer-switch-hover-bg); --switch-hover-icon: var(--footer-switch-hover-icon); --switch-pressed-bg: var(--footer-switch-pressed-bg); --switch-pressed-icon: var(--footer-switch-pressed-icon); display: none; margin-top: 18px; }
.legal { display: flex; justify-content: space-between; padding-top: 18px; color: var(--footer-legal); font-size: 12.5px; }

/* ---------- Call bar ---------- */
/* A call button fixed to the foot of the screen on phones. It is in the page at every width and shown only at
   720px and below (see "720px and below"), where the page keeps room for it at the end and above any field that
   scrolls into view. It does not move: no animation and no transition. */
.call-bar { position: fixed; right: 0; bottom: 0; left: 0; z-index: 5; display: none; align-items: center; justify-content: center; gap: 10px; height: var(--call-bar-height); background: var(--action); box-shadow: var(--call-bar-shadow); color: var(--on-action); font-size: 16px; font-weight: 700; white-space: nowrap; }
.call-bar:hover { background: var(--action-hover); }
.call-bar:focus-visible { outline-color: var(--focus-ring-on-band); outline-offset: -5px; }

/* ==========================================================================
   Tablets and phones
   The rules above are the desktop page. These adjust it at three widths, each block in page order:
   960px and below (tablets), 720px and below (large phones) and 560px and below (phones). One more block, for
   561px to 960px, holds what tablets have and phones do not, so the phone block never has to undo it.
   Before them comes the one exception to those three widths: a block for the menu bar alone, at 1099px and below.
   ========================================================================== */

/* ---------- 1099px and below: the menu bar alone ---------- */
/* In one row the bar needs 906px for the logo, the links, the switch and the phone button. From 1018px that leaves
   12px either side of the links, and 15px at an iPad's 1024px, where the name runs straight into "Services". So one
   row starts at 1100px, with 53px either side of the links. Below that, the links take a row of their own under the
   logo, the switch and the phone button, as on tablets. */
@media (max-width: 1099px) {
  .menu-bar { flex-wrap: wrap; }
  .menu { order: 1; width: 100%; }
  .menu-links { justify-content: center; padding-block: 12px 6px; }
}

/* ---------- 960px and below ---------- */
@media (max-width: 960px) {
  /* Paragraphs avoid ending on a word alone. */
  p { text-wrap: pretty; }

  /* Menu bar: the phone button is at least 44px tall to tap however it is drawn, and the switch beside it is as tall,
     and as wide as on a desktop. Each of the switch's buttons is as tall as the switch too, so a finger can press it
     anywhere from the switch's top edge to its foot: 44px, over the switch's padding and border. Its tint and focus
     ring stay the 28px circle under the icon, drawn here on a layer of their own (::before) instead of the button. */
  .menu-phone { min-height: 44px; }
  .menu-actions .theme-switch { min-height: 44px; }
  .menu-actions .theme-switch button, .menu-actions .theme-switch button:hover, .menu-actions .theme-switch button[aria-pressed="true"] { position: relative; height: 44px; margin-block: -4px; border-radius: 0; background: none; }
  .menu-actions .theme-switch button::before { content: ""; position: absolute; top: 8px; left: 0; width: 28px; height: 28px; border-radius: 50%; }
  .menu-actions .theme-switch button:hover::before { background: var(--switch-hover-bg); }
  .menu-actions .theme-switch button[aria-pressed="true"]::before { background: var(--switch-pressed-bg); }
  .menu-actions .theme-switch .icon { position: relative; }
  .menu-actions .theme-switch button:focus-visible { outline: none; }
  .menu-actions .theme-switch button:focus-visible::before { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

  /* Top section: one column, the words first, then the photos, to the right as on a desktop. 680px is the content
     width at 768px (768 - 2 x 44px), so a tablet held upright uses the full width and wider screens no more. */
  .hero-grid { grid-template-columns: minmax(0, 1fr); gap: 44px; padding-block: 36px 60px; }
  .hero-photos { width: 100%; max-width: 680px; height: auto; margin-left: auto; aspect-ratio: 3 / 2; }
  /* 84% is close to the desktop's share, where the large photo is 298px of its 352px group (84.66%). 44% (the
     desktop's 150px would be 42.6%) keeps the small photo, 45% wide, close to its own 3:2 shape. */
  .hero-photo-large { height: 84%; }
  .hero-photo-small { height: 44%; }
  .badge-certified { right: 14px; }

  /* Call-back band: the heading above the form. The fields' text is 16px, not the mockup's 15px: Safari on an iPhone
     zooms the page in on a field whose text is under 16px when it takes focus, and the page then pans sideways. */
  .callback-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .field input, .field textarea { font-size: 16px; }

  /* Services: two columns. */
  .service-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Why us: the words above the photo, and the badge over the photo's lower edge. 16:9 keeps the photo under
     500px tall at 960px with the man and his hands in frame. The section's 56px foot gains the 20px the badge
     hangs below the photo. */
  .why-grid { grid-template-columns: minmax(0, 1fr); gap: 36px; padding-bottom: 76px; }
  .why-photo { order: 1; }
  .why-photo img { height: auto; aspect-ratio: 16 / 9; object-position: center; }
  .years-badge { right: 24px; bottom: -20px; }
  .why .section-intro { max-width: none; }

  /* Reviews: the quote above the rating (laid out in a row from 561px to 960px, below). */
  .reviews { grid-template-columns: minmax(0, 1fr); }

  /* Call band: the words above the buttons. The faint circle moves to the lower-right corner so it never passes
     behind the words: 300px across with a 28px edge and centred on that corner (right and bottom -150px), it
     shows a quarter ring 122px to 150px from the corner, and the words stay further away than that at every width
     here. At 560px and below the ring runs behind the stacked buttons; wider, it sits in the corner beside them,
     just reaching the end of "Send a message" at the narrowest of those widths. */
  .call-band { flex-direction: column; align-items: flex-start; }
  .call-band::after { top: auto; right: -150px; bottom: -150px; width: 300px; height: 300px; border-width: 28px; }

  /* Footer: the logo and its line across the top, the three lists in a row below. */
  .footer-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .footer-brand { grid-column: 1 / -1; }
}

/* ---------- 561px to 960px ---------- */
@media (min-width: 561px) and (max-width: 960px) {
  /* Reviews: the rating in one row, the score, then the stars over the count, then the link. */
  .rating-box { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 20px; padding-block: 24px; }
  .rating-score { grid-row: span 2; margin-bottom: 0; }
  .rating-box .stars { margin-bottom: 4px; }
  .rating-link { grid-area: 1 / 3 / span 2; align-self: center; margin-top: 0; }
}

/* ---------- 720px and below ---------- */
@media (max-width: 720px) {
  /* The desktop's 44px side margins are too wide for a phone. */
  :root { --gutter: 24px; }
  /* Keep room for the call bar: at the end of the page, and below anything brought into view, such as a field
     the keyboard moves to. That room is 12px more than the bar, so a field never sits flush against it, and never
     half a pixel under it when the browser rounds the scroll position to a whole pixel. */
  html { scroll-padding-bottom: calc(var(--call-bar-height) + 12px); }
  body { padding-bottom: var(--call-bar-height); }
  .call-bar { display: flex; }

  /* Menu bar: the links are left to the footer, leaving the logo and the phone button, and the switch moves to the
     footer too. */
  .menu { display: none; }
  .menu-actions .theme-switch { display: none; }

  /* Top section: the headline shrinks with the screen and keeps its two lines. 11vw - 4px keeps its longer line
     (8.3172em) at about 92% of the 100vw - 40px content width from 320px to 560px, and reaches 60px at 582px. Here its
     lines may wrap: in English neither does, with that 8% to spare, and a browser's translation, whose words can be
     longer, takes more lines instead of running off the side of the phone. */
  .hero-title { font-size: clamp(28px, 11vw - 4px, 60px); white-space: normal; }

  /* How it works: one step under another, each number beside its words. */
  .step-list { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .step { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 16px; padding: 20px; }
  .step-number { grid-row: span 2; margin-bottom: 0; }

  /* Privacy and not-found pages: less room around the text, and a smaller heading. */
  .text-page { padding-block: 40px 56px; }
  .text-page h1 { font-size: 36px; }

  /* Footer: its links stand in for the menu, so each gets a 34px row to tap (20px of text, 7px above and below).
     Its copy of the switch shows under the logo and its line, with buttons 44px across. */
  .footer-links li { padding-block: 0; }
  .footer-links a, .footer-links .footer-hours { display: block; padding-block: 7px; }
  .site-footer .theme-switch { display: flex; }
  .site-footer .theme-switch button { width: 44px; height: 44px; }
  .site-footer .theme-switch .icon { width: 18px; height: 18px; }
}

/* ---------- 560px and below ---------- */
@media (max-width: 560px) {
  :root { --gutter: 20px; }

  /* Top bar: the hours stay at the right edge, and the service area gives way. The "Open now" sign, shown by a
     script once the page has loaded, then appears to their left and nothing moves. */
  .top-bar-row { justify-content: flex-end; }
  .top-bar-area { display: none; }

  /* Menu bar: the logo shrinks with the screen, and the phone button keeps only its icon. The call bar shows the
     number, and the number, hidden from view, still names the button for screen readers.
     The desktop logo is a 25px name, a 58px mark (2.32em) and a 12px gap (.48em): 12.95em in all. Its size runs
     from 17px at 320px (a 220px logo, then 16px of space and the 44px button fill 280px) to 25px from 462px. */
  .logo { gap: .48em; height: auto; font-size: clamp(17px, 5.7vw - 1.3px, 25px); }
  .logo-mark { width: 2.32em; }
  .logo-name { font-size: 1em; }
  .menu-phone { justify-content: center; width: 44px; height: 44px; padding: 0; }
  .menu-phone .icon { width: 18px; height: 18px; }
  .menu-phone-number { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

  /* Top section: the buttons one above the other across the full width. The large photo takes the full width,
     8:5, a little shallower than its own 3:2, keeps the group compact: 279px tall at 390px rather than 293px. The
     small photo overlaps its lower corner and the 60px below it. The "On-site" badge rises 24px above the photo (the
     52px gap keeps it 28px clear of the rating line); the "CompTIA A+" badge sits over the large photo's lower edge.
     The small photo is 44% of the group but always leaves 186px for the CompTIA badge beside it (the badge is
     177px wide, at the right edge, so that is a 9px gap): below 373px it is 186px short of the full width, 94px
     wide at 320px. */
  .hero-actions { flex-direction: column; }
  .hero-actions .button { justify-content: center; }
  .hero-grid { gap: 52px; }
  .hero-photos { aspect-ratio: auto; padding-bottom: 60px; }
  .hero-photo-large { position: relative; width: 100%; height: auto; aspect-ratio: 8 / 5; }
  .hero-photo-small { width: min(44%, 100% - 186px); height: auto; aspect-ratio: 3 / 2; }
  .badge-onsite { top: -24px; left: 12px; }
  .badge-certified { right: 0; bottom: 26px; }

  /* Call-back band: the fields one above another, and the button across the full width. */
  .callback-fields { grid-template-columns: minmax(0, 1fr); }
  .field-row { flex-direction: column; align-items: stretch; }

  /* Services: one column, each card with its icon beside its words. */
  .service-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .service { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 14px; }
  .service .icon-tile { grid-row: span 2; margin-bottom: 0; }

  /* Why us: the whole photo, with a smaller badge. */
  .why-photo img { aspect-ratio: 3 / 2; }
  .years-badge { right: 16px; padding: 13px 16px; }
  .years-number { font-size: 26px; }
  .years-text { font-size: 12px; }

  /* Reviews: a smaller quote and less padding; the rating keeps the desktop's column. */
  .review-quote { padding: 26px 24px; }
  .review-quote blockquote p { font-size: 19px; }
  .rating-box { padding: 26px 24px; }

  /* Call band: the buttons one above the other. */
  .call-band { padding: 28px 24px; }
  .call-band-actions { flex-direction: column; align-self: stretch; }
  .call-band-actions .button { justify-content: center; }

  /* Privacy and not-found pages: a smaller heading, and the not-found page's buttons one above the other across the
     full width, as at the top of the home page. */
  .text-page h1 { font-size: 32px; }
  .text-page-actions { flex-direction: column; }
  .text-page-actions .button { justify-content: center; }

  /* Footer: the first two lists side by side, and the contact list across the width under them. */
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 28px; }
  .footer-contact { grid-column: 1 / -1; }
}
