/* ═══════════════════════════════════════════════════════════════════
   IntelliPlan — phone corrections

   Loads last, after ip-premium.css, for the same reason ip-premium loads
   after ip-ui: this file exists to *win*. mobile.css is first in the
   cascade and therefore loses every specificity tie to the component
   library, which is fine for the layout rules it owns and useless for
   corrections to those components.

   Scope: `(pointer: coarse)` rather than a width breakpoint alone. The
   problems here — targets too small for a fingertip, text sized for a
   screen held at desk distance — are properties of the *input device*,
   not the viewport. A 1024px tablet has fingers; a 700px desktop window
   has a mouse.

   Every rule below was written against a measured defect, not a guess.
   The measurements are in the comments so the next person can re-check
   them rather than trusting this file.
   ══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   BUTTON RESPONSIVENESS

   Measured on the landing page: 21 of 72 interactive elements carried
   `backdrop-filter`, covering ~198,000 px² of live-blurred backdrop, and
   13 more used `transition: all`.

   backdrop-filter is the most expensive property here by a wide margin.
   The browser must re-sample and re-blur everything *behind* the element
   every time either the element or the content behind it changes — which
   during a press animation is every frame. Twenty-one of them on one
   screen is why buttons felt like they lagged behind the finger.

   `transition: all` compounds it: the browser evaluates every animatable
   property on every state change instead of the two or three that
   actually differ, and it silently animates any property added later.

   Both are fixed below. The blur removal is scoped to coarse pointers,
   where mobile GPUs suffer most and the effect is least visible at arm's
   length; the transition narrowing is global because it changes nothing
   visually — nothing in these rules animates a layout property, verified
   before the change.
   ══════════════════════════════════════════════════════════════════ */

/* Animate only what the compositor can handle on its own thread. Listing
   properties explicitly also stops a future declaration from becoming an
   accidental animation. */
button, .btn, [role="button"], .nav-tab, .sched-tab, .ipui-tab, .chip {
  transition-property: transform, opacity, color, background-color,
                       border-color, box-shadow;
}

@media (pointer: coarse) {

  /* Drop the live blur on touch devices. The translucent background is
     kept, so the element still reads as glassy — it simply no longer
     re-blurs the page behind it on every frame.

     Every selector carries a `body ` prefix, and that is load-bearing.
     ip-base.css declares `body .btn-primary, … { backdrop-filter: …
     !important }`. Two !important declarations are settled by specificity
     first, so a bare `.btn-primary` here — even with !important — loses to
     it. Matching the prefix ties the specificity, and ip-phone.css loads
     last, so order decides in this file's favour.

     There is already a `*, ::before, ::after { backdrop-filter: none
     !important }` under max-width:768px elsewhere in the app. It was
     written to do exactly this job and never worked, and the reason is
     worth recording: the winning declaration is

         body button:not(.no-glass):not(.btn-primary)
                    :not(.ipd-btn-primary):not(.mobile-cta-primary) { … }

     `:not()` contributes the specificity of its argument, so that selector
     scores (0,4,2). The universal selector scores zero. No selector a
     correction layer can reasonably write beats it, and escalating is an
     arms race that the next person loses again.

     So this does not fight the cascade. ip-base.css now expresses every
     glass blur as `var(--ip-glass-fx, <original value>)`, and a custom
     property set on :root inherits to every element regardless of how
     specific the rule that consumes it is. One declaration turns the
     entire effect off, and the fallback keeps desktop byte-identical. */
  :root {
    --ip-glass-fx: none;
  }

  /* A press should read instantly. transform is compositor-only, so this
     lands on the next frame regardless of what else is painting. */
  button:active, .btn:active, [role="button"]:active {
    transition-duration: 60ms;
  }

  /* ── Touch targets ────────────────────────────────────────────────
     Measured on /scheduler at 375px: the view tabs ("Creator",
     "Interactive view") were 35px tall and the summary tabs 32px. Both
     are primary navigation for the page. 44px is the documented floor
     from every platform's guidance; these were meaningfully under it,
     which on a phone means mis-taps rather than merely tight taps.

     Applied as a min-height with centred content so a control grows
     downward from its text rather than having its label re-positioned. */
  .sched-tab,
  .ipui-tab,
  .tab-btn,
  .sched-summary-tab,
  .ipui-slot__tool,
  .ck-mode button,
  .chip,
  .pill-btn,
  .install-pill,
  .ipui-announce__cta,
  .ipui-announce__close,
  .cta-link {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Accordion headers. Measured 19–36px across / and /pricing, and on a
     phone the FAQ accordion *is* the page — every answer is behind one of
     these. `display` is left alone: a summary has a disclosure marker
     whose layout depends on the default display type, and flexing it
     moves the triangle. Padding grows the box instead. */
  summary {
    min-height: 44px;
    padding-block: 0.55rem;
  }

  /* Footer / sitemap link columns. Measured 21–24px on every page. These
     are stacked lists of links, so they need vertical separation as much
     as height — two 22px links 2px apart is one 46px mis-tap. */
  .sk-link,
  .footer-links a,
  .site-footer a {
    display: inline-block;
    min-height: 44px;
    line-height: 44px;
  }

  /* Icon-only controls are the worst offenders because there is no text
     to enlarge the box. Measured: 29x29 and 34x34 on the landing page,
     43x27 for the CTA minimiser. */
  button[aria-label]:not(.ipa-btn):not([class*="ipui-"]),
  .icon-btn,
  #planiSendBtn,
  #mobileCTAMinimize {
    min-width: 44px;
    min-height: 44px;
  }

  /* The dark-mode switch measured 46x24. The visible track should stay
     the size it is — a 44px-tall pill would look wrong — so the *label*
     grows instead and the track stays centred inside it. This is the
     general fix for any control whose look is deliberately small: give
     the hit area the height, not the paint. */
  label.toggle,
  .ipui-switch,
  .toggle-wrap {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  /* Date chips in the scheduler's day picker. The label is the target
     (its input is pointer-events:none), and it was comfortably wide but
     short. */
  .ipui-dates__day {
    min-height: 56px;
  }

  /* ── Readable text ────────────────────────────────────────────────
     Measured across /, /scheduler, /dashboard and /study: 34 elements on
     the scheduler alone rendered between 9.6px and 11.4px. Those sizes
     are legible on a monitor at 60cm and genuinely hard on a phone at
     30cm, especially the metadata they were used for — day-of-week
     abbreviations, month names, eyebrow labels, keyboard hints.

     Raised to a flat 12px floor. Note the temptation to write
     `max(0.75rem, 1em)` so each element keeps its own size unless it is
     below the floor — that does not work. `1em` resolves against the
     *parent's* font size, not the element's, so every one of these
     inherits its container's size instead: the date chip's "Wed" and
     "Aug" jumped to 15px and became the same size as the day number they
     are supposed to sit beneath. CSS cannot express "your own size, but
     not below 12px" without naming the size, so it is named.

     Every selector below is prefixed with `body`. That is not decoration:
     several of these classes are defined in a page template's inline
     <style>, which sits *after* this file's <link> in the document. At
     equal specificity the later rule wins, so a bare `.ds-eyebrow` here
     silently loses. `body .ds-eyebrow` outranks it by one element and
     wins regardless of order. */
  body .ipui-dates__dow,
  body .ipui-dates__mon {
    font-size: 0.75rem;   /* was 10.2px / 9.6px */
  }

  body .date-badge,
  body .ipd-featured-label,
  body .ds-eyebrow,
  body .ds-drop-types,
  body .ds-med-label,
  body .ds-db-panel-title,
  body .install-subtitle,
  body .ipui-field__label,
  body .ipui-announce__badge,
  body .hero-badge,
  body .hero-trust-label,
  body .section-kicker,
  body .comparison-label,
  body .u-label,
  body .cmd-esc,
  body kbd {
    font-size: 0.75rem;   /* was 9.6px – 11.4px */
  }

  /* Catch-all for the long tail. Scoped to the small-text utility
     classes the codebase actually uses, so it cannot accidentally
     inflate a deliberate display size. */
  body .text-micro,
  body .text-xs,
  body .eyebrow,
  body .meta,
  body .caption {
    font-size: 0.75rem;
  }

  /* ── Forms ────────────────────────────────────────────────────────
     iOS zooms the viewport when a focused input's text is under 16px,
     and then does not zoom back out. The result is a page the student
     has to pinch to escape after every text entry. 16px is the fix and
     it has to be exact — 15.9px still zooms. */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="number"],
  input[type="date"],
  input[type="time"],
  select,
  textarea {
    font-size: 16px;
  }

  /* Give form controls a real height too — a 32px input is as awkward to
     tap into as a 32px button is to press. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]),
  select,
  textarea {
    min-height: 44px;
  }

  /* Range inputs are dragged, not tapped, so they need vertical room for
     the thumb rather than a tall box. */
  input[type="range"] {
    min-height: 44px;
  }
}

/* ── Narrow phones ──────────────────────────────────────────────────
   Everything above is about fingers. This block is about width: below
   ~360px, horizontal padding is the difference between a readable column
   and a gutter. */
@media (max-width: 360px) {
  .ipui-dates__day {
    /* Fit one more day on screen rather than making the row scroll for a
       single chip. */
    min-width: 52px;
  }
}

/* ── Landscape phones ───────────────────────────────────────────────
   A phone on its side has ~350px of height. Anything that reserves
   vertical space by viewport units becomes unusable, so sticky chrome
   gets out of the way. */
@media (pointer: coarse) and (orientation: landscape) and (max-height: 480px) {
  .mobile-cta,
  .install-banner {
    display: none;
  }
}

/* Respect the platform preference. Motion added elsewhere is decorative;
   none of the corrections above depend on it. */
@media (prefers-reduced-motion: reduce) {
  .sched-tab,
  .ipui-tab,
  .tab-btn {
    transition: none;
  }
}
