/*
 * Shahzeb Speaks — UX and accessibility corrections
 * Loaded last, so these rules win without editing any existing stylesheet.
 *
 * Every value here came from measuring the live site, not from taste:
 *   · 11 of 12 body paragraphs rendered below 16px on a 375px viewport
 *   · 40 of 98 tap targets were smaller than the 44px minimum
 *   · 73 elements carried a backdrop blur, which is expensive on the
 *     mid-range Android hardware most of the traffic uses
 *
 * Deliberately conservative: it raises floors and never changes a colour, a
 * layout or a font family, so it cannot alter the look on desktop.
 */

/* ==========================================================================
   1. Readable body text on phones
   Google flags sub-16px body copy in Mobile Usability, and readers simply
   leave. Headings and deliberately small labels are left alone.
   ========================================================================== */
@media (max-width: 768px) {

    body,
    p,
    li,
    dd,
    blockquote,
    .entry-content p,
    .post-content p,
    .service-description,
    .card-description,
    .section-subtitle {
        font-size: 16px;
        line-height: 1.7;
    }

    /* Lead paragraphs stay a step larger than body copy. */
    .hero p,
    .hero-subtitle,
    .lead,
    .section-lead,
    .apps-lead,
    .adev-lead,
    .iolist-lead,
    .ioapp-lead {
        font-size: 16px;
        line-height: 1.65;
    }

    /* Genuinely secondary text keeps a smaller size, but not a tiny one. */
    small,
    figcaption,
    .meta,
    .post-meta,
    .badge,
    .tag,
    .chip,
    .breadcrumb {
        font-size: 14px;
    }
}

/* ==========================================================================
   2. Tap targets
   44px is the accessibility minimum. Padding is used rather than height so
   nothing is stretched or clipped.
   ========================================================================== */
@media (max-width: 1024px) {

    nav a,
    .nav-link,
    .menu-item a,
    .mobile-menu a,
    .footer-links a,
    .footer a {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
    }

    button,
    .btn,
    input[type="submit"],
    input[type="button"],
    .wp-block-button__link {
        min-height: 44px;
    }

    /* Icon-only controls need width as well as height. */
    .icon-btn,
    .social-link,
    .share-btn,
    .cart-icon,
    .search-toggle,
    .menu-toggle {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

/* ==========================================================================
   3. Form fields
   Any input below 16px makes iOS Safari zoom the whole page on focus, which
   readers experience as the layout jumping.
   ========================================================================== */
input,
textarea,
select {
    font-size: 16px;
}

@media (max-width: 1024px) {

    input:not([type="checkbox"]):not([type="radio"]),
    textarea,
    select {
        min-height: 44px;
    }
}

/* ==========================================================================
   4. Motion and blur
   Backdrop blur is the single most expensive effect on a low-end GPU. Phones
   drop it; desktops keep the glass look untouched.
   ========================================================================== */
@media (max-width: 768px) {

    [class*="glass"],
    .card,
    .service-card,
    .portfolio-card,
    header,
    .site-header {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
    }
}

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   5. Keyboard focus
   Several controls had no visible focus ring, which makes the site unusable
   without a mouse.
   ========================================================================== */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid #00D4FF;
    outline-offset: 3px;
    border-radius: 4px;
}

/* ==========================================================================
   6. Long-word overflow
   Long URLs and technical terms were pushing narrow cards sideways.
   ========================================================================== */
p,
li,
h1,
h2,
h3,
h4,
.card,
.entry-content {
    overflow-wrap: break-word;
}

/* Headings read better when the last line is not a single orphan word. */
h1,
h2,
h3 {
    text-wrap: balance;
}

/* ==========================================================================
   7. Homepage FAQ
   Added so the FAQ structured data describes content a visitor can actually
   see. Google requires that; schema without visible content is a policy
   violation and risks every rich result on the site.
   ========================================================================== */
.ss-faq-section {
    padding: 70px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.ss-faq-section .ss-faq-head {
    max-width: 820px;
    margin-bottom: 30px;
}

.ss-faq-section h2 {
    font-size: 2rem;
    letter-spacing: -1px;
    margin-bottom: 12px;
}

.ss-faq-section .ss-faq-head p {
    color: var(--text-muted);
    line-height: 1.8;
}

.ss-faq-list {
    max-width: 900px;
}

.ss-faq-list details {
    background: var(--bg-card);
    border: var(--glass-border);
    border-radius: 12px;
    padding: 20px 24px;
    margin-bottom: 12px;
}

.ss-faq-list summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 1rem;
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
}

.ss-faq-list summary::-webkit-details-marker {
    display: none;
}

.ss-faq-list summary::after {
    content: "\f078";
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    font-size: 0.75rem;
    color: #00D4FF;
    transition: transform 0.25s ease;
    flex: 0 0 auto;
}

.ss-faq-list details[open] summary::after {
    transform: rotate(180deg);
}

.ss-faq-list details p {
    margin: 14px 0 0;
    color: var(--text-muted);
    line-height: 1.8;
}

@media (max-width: 768px) {
    .ss-faq-section {
        padding: 46px 0;
    }

    .ss-faq-section h2 {
        font-size: 1.75rem;
    }
}

/* ==========================================================================
   Desktop target size (WCAG 2.2 AA, 2.5.8)
   The mobile block above uses the 44px AAA figure. On desktop the AA floor is
   24x24, and only six links miss it: the footer legal row and the two office
   addresses sit at 22px tall. Two pixels of padding clears it without moving
   anything else, because these are inline-level links inside a flex row.
   ========================================================================== */
.footer-bottom a,
.footer-legal a,
.contact-row,
.dmca-badge-link {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
}

/* ==========================================================================
   Three gaps the token pass could not reach
   ========================================================================== */

/* 1. Headings nothing styles.
   Twelve h3 elements on the homepage (.trust-card, .quick-nav-card,
   .footer-col) have no font-size rule at all, so they render at the browser
   default 18.72px, the one size left off the scale. :where() carries zero
   specificity, so this is a floor: every existing rule still wins, and only
   headings with no rule of their own are affected. Verified first that no
   bare h1..h6 font-size rule exists in the theme, which is what would have
   made this override something on purpose. */
:where(h1) { font-size: 3rem; }
:where(h2) { font-size: 2rem; }
:where(h3) { font-size: 1.125rem; }
:where(h4) { font-size: 1rem; }
:where(h5),
:where(h6) { font-size: 0.875rem; }

/* 2. Cart badge contrast.
   White on rgb(239,68,68) measures 3.76:1 at 12px, under the 4.5:1 AA line.
   #C81E3A measures 5.67:1 and still reads as the same red. */
.cart-badge,
.header-cart-count {
    background: #C81E3A;
}

/* 3. The struck-through former price.
   .price-was sits at rgba(255,255,255,0.3), which measures 2.53:1. The token
   pass leaves alphas under 0.4 alone because that range is decorative glyphs,
   but this one is a number a buyer reads, so it is raised here by name rather
   than by loosening the rule for everything. */
.home-product-price .price-was,
.price-was,
.product-price-original {
    color: rgba(255, 255, 255, 0.6);
}

/* ==========================================================================
   Hero clearance under the fixed header
   The navbar is position:fixed and 90px tall on desktop, 98px on mobile, but
   the hero only reserved 80px of padding. The first thing in the hero is the
   "Available for new projects" badge, so its top 10px sat underneath the bar
   and the pill read as clipped. Measured, not guessed: badge top 80px, navbar
   bottom 90px.
   ========================================================================== */
.hero,
.hero-ultra-premium,
.apps-hero,
.ba-wrap {
    padding-top: 124px;
}

@media (max-width: 768px) {
    .hero,
    .hero-ultra-premium,
    .apps-hero,
    .ba-wrap {
        padding-top: 132px;
    }
}

/* ==========================================================================
   Homepage: the free audit tool block
   Deliberately NOT a card grid. Every other section on this page is three
   cards in a row, so a section that is one composition is the only way this
   one reads as different rather than as the next row of the same thing.
   ========================================================================== */
.home-audit-tool-section {
    padding: 60px 0 20px;
}
.hat-inner {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    gap: 40px;
    align-items: center;
    padding: 44px;
    border-radius: 20px;
    border: var(--glass-border);
    background:
        radial-gradient(120% 140% at 0% 0%, rgba(0, 110, 255, .14) 0%, transparent 60%),
        var(--bg-card);
}
.hat-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 18px;
    border-radius: 50px;
    background: rgba(0, 110, 255, .12);
    border: 1px solid rgba(0, 110, 255, .3);
    color: #00D4FF;
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: 18px;
}
.hat-copy h2 {
    font-size: 2rem;
    line-height: 1.2;
    margin: 0 0 14px;
    max-width: 18ch;
}
.hat-copy p {
    color: var(--text-muted);
    line-height: 1.8;
    margin: 0 0 22px;
    max-width: 54ch;
}
.hat-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: linear-gradient(135deg, #006EFF, #00D4FF);
    color: #fff;
    font-weight: 600;
    padding: 15px 28px;
    border-radius: 12px;
    text-decoration: none;
    min-height: 44px;
}
.hat-btn:hover { color: #fff; transform: translateY(-2px); }
.hat-note {
    font-size: 0.875rem;
    margin: 14px 0 0 !important;
    color: var(--text-muted);
}
.hat-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 12px;
}
.hat-list li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    color: var(--text-muted);
    line-height: 1.6;
}
.hat-list i {
    color: #00D4FF;
    margin-top: 4px;
    flex: 0 0 auto;
}

@media (max-width: 900px) {
    .hat-inner { grid-template-columns: 1fr; gap: 28px; padding: 32px 24px; }
    .hat-copy h2 { font-size: 1.5rem; max-width: none; }
}

/* ==========================================================================
   Mobile touch targets, measured rather than guessed
   The existing block above covers .btn, nav links and form controls. These
   eight classes are not any of those, so they were never picked up. Measured
   at 375px: .masterpiece-details-link 157x40 (x6), .footer-social-btn 40x40
   (x8), .side-cart-close 40x44, .btn-newsletter 40x44, .logo 200x38.

   None of these fail WCAG 2.2 AA, which sets the floor at 24x24, and none was
   under 24px. They miss the 44px figure Apple uses, and a 40x40 social icon on
   a phone is genuinely fiddly to hit, so it is worth the four pixels.
   ========================================================================== */
@media (max-width: 1024px) {
    .masterpiece-details-link,
    .footer-social-btn,
    .side-cart-close,
    .btn-newsletter,
    .hat-btn,
    .ba-form button {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* The logo is a link, not a control, but it is the one people tap to get
       home, so it gets the same floor. */
    .logo {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
    }
}

/* The last seven, measured after the block above shipped: .back-to-top at
   40x40, and the footer legal and address rows sitting at exactly 24px because
   that is the floor the desktop rule set. 24 clears WCAG 2.2 AA, but these are
   links people tap with a thumb, so on a phone they get the full 44. */
@media (max-width: 1024px) {
    .back-to-top {
        min-width: 44px;
        min-height: 44px;
    }

    .footer-bottom a,
    .footer-legal a,
    .contact-row,
    .dmca-badge-link {
        min-height: 44px;
    }
}

/* ==========================================================================
   Email capture
   Replaces the footer box whose form had no action, no method and a
   type="button" submit, so every address typed into it went nowhere.
   ========================================================================== */
.sub-box { max-width: 820px; margin: 0 0 26px; }
.sub-heading { font-size: 1.5rem; margin: 0 0 8px; }
.sub-blurb { color: var(--text-muted); line-height: 1.75; margin: 0 0 16px; }

.sub-form { display: flex; gap: 10px; flex-wrap: wrap; }
.sub-input {
    flex: 1 1 240px;
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 10px;
    padding: 13px 16px;
    color: var(--text-main);
    font-family: inherit;
    font-size: 1rem;
    min-height: 44px;
}
.sub-input:focus { outline: 2px solid #00D4FF; outline-offset: 2px; border-color: transparent; }
.sub-btn {
    background: linear-gradient(135deg, #006EFF, #00D4FF);
    color: #fff;
    border: 0;
    font-family: inherit;
    font-weight: 600;
    font-size: 1rem;
    padding: 13px 24px;
    border-radius: 10px;
    cursor: pointer;
    min-height: 44px;
}
.sub-btn:hover { transform: translateY(-1px); }

/* The honeypot. Not display:none: some bots skip anything hidden that way,
   and a few screen readers announce it anyway. Off-canvas with aria-hidden
   keeps it out of sight and out of the accessibility tree while staying a
   real, fillable field to anything reading the markup. */
.sub-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.sub-note { margin: 0 0 14px; padding: 12px 16px; border-radius: 10px; line-height: 1.6; }
.sub-note-good { background: rgba(0, 200, 120, .12); border: 1px solid rgba(0, 200, 120, .35); color: #3ddc97; }
.sub-note-bad  { background: rgba(200, 30, 58, .12); border: 1px solid rgba(200, 30, 58, .4); color: #ff8fa3; }
.sub-fine { font-size: 0.875rem; color: var(--text-muted); margin: 12px 0 0; }

/* In the footer column the box is narrow, so the field and button stack. */
.footer-col .sub-box { margin: 0; }
.footer-col .sub-form { flex-direction: column; }
.footer-col .sub-input,
.footer-col .sub-btn { flex: 1 1 auto; width: 100%; }

/* ==========================================================================
   Trust figures: a row, not four more cards
   Ten of the fifteen homepage sections are card grids, which is the single
   biggest reason the page reads as generated rather than designed. This is the
   first section moved off that pattern. The content is untouched: same four
   numbers, same labels, same sentences. What changes is that they stop wearing
   borders they did not earn. A card should be a thing you click.
   ========================================================================== */
.trust-figures {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0;
    max-width: 1000px;
    margin: 0 auto;
}
.trust-figure {
    padding: 8px 28px;
    border-left: 1px solid rgba(255, 255, 255, .09);
}
.trust-figure:first-child {
    border-left: 0;
    padding-left: 0;
}
.trust-figure .trust-number {
    display: block;
    font-size: 3rem;
    font-weight: 800;
    line-height: 1;
    margin-bottom: 10px;
    background: linear-gradient(135deg, #006EFF, #00D4FF);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.trust-figure h3 {
    font-size: 1.125rem;
    margin: 0 0 6px;
}
.trust-figure p {
    color: var(--text-muted);
    line-height: 1.6;
    margin: 0;
    font-size: 1rem;
}

@media (max-width: 900px) {
    .trust-figures { grid-template-columns: repeat(2, 1fr); gap: 32px 0; }
    .trust-figure:nth-child(odd) { border-left: 0; padding-left: 0; }
}
@media (max-width: 520px) {
    .trust-figures { grid-template-columns: 1fr; gap: 28px; }
    .trust-figure { border-left: 0; padding: 0; }
    .trust-figure .trust-number { font-size: 2.5rem; }
}

/* ==========================================================================
   Two more sections off the card grid
   Measured rather than assumed: of the ten card sections on the homepage, only
   these two hold cards nobody can click. .psych-home-card (4) and .webdev-card
   (6) are icon + heading + paragraph, with no link anywhere inside them. A card
   should be a thing you click; these are just text wearing a border.

   The other eight sections keep their cards, because those cards ARE the
   interaction: portfolio items, audits, products, posts, nav tiles. And
   .why-card was already borderless and padding-free, so it was never a card to
   begin with, whatever its name says.

   The icons keep their colours. Magenta on the psychology cards and cyan on the
   development ones is the same blue/purple split the rest of the site uses to
   say which of the two jobs a thing belongs to. That is meaning, not chrome.
   ========================================================================== */
.psych-home-card,
.webdev-card {
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0 24px 0 0;
}

.psych-home-card:hover,
.webdev-card:hover {
    background: none;
    transform: none;
    border-color: transparent;
}

/* Grid gap does the separating now that the borders are gone. */
.psych-home-grid,
.psychology-cards-home,
.webdev-grid,
.webdev-services-grid {
    gap: 40px 32px;
}

@media (max-width: 900px) {
    .psych-home-card,
    .webdev-card { padding: 0; }
}

/* ==========================================================================
   Footer social row: let it wrap on a phone
   Measured on the live site at 375px: the row is one nowrap line of eight
   44x44 buttons with 15px gaps = 457px inside a 343px column. The last two
   sit past the viewport edge: TikTok is half cut and the RSS icon is
   entirely off-screen, so a tap at its centre lands on TikTok instead. The
   page itself does not scroll sideways, which is why this was invisible -
   nothing overflows the document, only the column.

   Wrapping fixes it without touching sizes: 6 icons on the first line, 2 on
   the second, all still 44x44. Above 1024px the row is 457px inside a much
   wider column, so wrap never triggers and the desktop footer is unchanged.
   ========================================================================== */
@media (max-width: 1024px) {
    .footer-social-icons {
        flex-wrap: wrap;
        gap: 12px;
    }
}

/* ==========================================================================
   Header: the nav pill overlapped the logo and the cart on every desktop width
   Measured at 1375px (2026-09-19): logo 200px + pill 760px + actions 205px =
   1,165px inside a 1,136px container (max-width 1200 minus 32px padding each
   side). The pill is absolutely centred, so it slid 12px over the logo and
   17px over the cart. The ninth nav item (Free Tools, added 2026-09) is what
   pushed the pill past the space it had.

   Fix: put the pill back in the flex row (it can no longer overlap anything,
   because flex items do not stack) and give the links less side padding.
   Pill widths measured at 14px: 16px padding = 760, 10px = 669. At 13px with
   8px padding it is about 602, which still fits the 632px left at 1101px.
   ========================================================================== */
@media (min-width: 1101px) {
    .nav-container .nav-pill-container {
        position: static;
        left: auto;
        transform: none;
        margin: 0 auto;
        flex: 0 1 auto;
    }

    .nav-container .nav-links a {
        padding-left: 10px;
        padding-right: 10px;
    }
}

@media (min-width: 1101px) and (max-width: 1199px) {
    .nav-container .nav-links a {
        padding-left: 8px;
        padding-right: 8px;
        font-size: 13px;
    }
}

/* ==========================================================================
   Brand audit pages: the sidebar did not stay with the reader
   The sidebar was moved by a scroll script that switches it between fixed
   and absolute. WP Rocket delays that script until the first interaction, so
   before it runs the sidebar simply scrolls away, and once it runs a 1,500px
   tall sidebar jumps between modes.

   Plain CSS sticky does this properly, but it was broken by overflow: hidden
   on BOTH html and body (brand-audits-styles.css tries overflow-x: clip on
   body, but html kept hidden, so body stayed a scroll container that never
   scrolls, and sticky had nothing to stick to). clip hides sideways overflow
   exactly like hidden but does not create a scroll container.

   The !important on position/top/left/width is deliberate: it overrides the
   inline styles the old script still writes, without editing the template.
   A sidebar taller than the screen scrolls inside itself.
   ========================================================================== */
@media (min-width: 1025px) {
    html:has(> body.single-brand_audit),
    body.single-brand_audit {
        overflow-x: clip !important;
        overflow-y: visible !important;
    }

    body.single-brand_audit .bas-sidebar-sticky {
        position: sticky !important;
        top: 96px !important;
        left: auto !important;
        bottom: auto !important;
        width: auto !important;
        max-height: calc(100vh - 116px);
        overflow-y: auto;
        scrollbar-width: thin;
        scrollbar-color: rgba(0, 212, 255, 0.35) transparent;
    }
}

/* ==========================================================================
   Brand audit pages: the floating share bar covered the start of the title
   The bar is fixed at 24px to 80px from the left edge, while the content
   starts 32px in whenever the window is narrower than 1,528px. On a 1,375px
   screen the first letters of every audit title sat underneath it. Pad the
   content clear of the bar in that range; wider screens already have room.
   ========================================================================== */
@media (min-width: 1025px) and (max-width: 1528px) {
    body.single-brand_audit .bas-wide-container {
        padding-left: 96px !important;
    }
}

/* ==========================================================================
   Blog articles: the same sidebar problem, plus a sidebar crushed to 46px
   single.php runs the same fixed/absolute scroll script on both article
   sidebars. Measured on /imposter-syndrome-at-work/ at 1375px: the script had
   written an inline width: 0px onto .right-sidebar-sticky, so every widget in
   it (reading progress, contents, related, tags) was squeezed to 46px, which
   is nothing but its padding. Same root cause as the audit pages: overflow
   hidden on html and body stops CSS sticky from working, so a script was
   used instead. Same fix: clip instead of hidden, then plain sticky, with
   !important to override the inline styles the script still writes.
   The share column shows from 993px and the right sidebar from 1201px, so
   the rules start at 993px and do nothing where those columns are hidden.
   ========================================================================== */
@media (min-width: 993px) {
    html:has(> body.single-post),
    body.single-post {
        overflow-x: clip !important;
        overflow-y: visible !important;
    }

    body.single-post .share-sticky,
    body.single-post .right-sidebar-sticky {
        position: sticky !important;
        top: 100px !important;
        left: auto !important;
        bottom: auto !important;
        width: auto !important;
    }

    body.single-post .right-sidebar-sticky {
        max-height: calc(100vh - 120px);
        overflow-y: auto;
        scrollbar-width: thin;
        scrollbar-color: rgba(0, 110, 255, 0.35) transparent;
    }
}

/* ==========================================================================
   About page: the registered company line under each entity card
   Added 2026-09-20 with the legal-name correction: the name was written
   without its space in 21 places across 10 template files.
   Quieter than the card text, so the card still reads as a description.
   ========================================================================== */
.brand-card .brand-legal {
    margin-top: 10px;
    font-size: 0.875rem;
    color: #8A94A8;
}

.brand-card .brand-legal strong {
    color: #c9d1df;
    font-weight: 600;
}
