/*
 * Tecnomation — responsive typography and measure.
 *
 * WHAT THIS IS, AND WHAT IT IS NOT
 *
 * This is not a design. The design is Exand's, and it stays: its colours, its
 * faces, its sections, its components, its animations, its header and footer.
 * This file changes none of that. What it does is make the type and the
 * measure behave at every width, which the theme does not do on its own:
 *
 *   - The hero heading was 72px at 1920 and still 72px at 1024, then fell to
 *     48 at 768 and 34 at 430. Three fixed values with cliffs between them.
 *     Everything here is a clamp() whose upper end is the value the design
 *     already used, so DESKTOP IS UNCHANGED and only the widths between the
 *     cliffs improve.
 *
 *   - Body copy ran the full width of its container: 1688px at 1920, about
 *     210 characters to the line. A line that long loses the reader on the
 *     carriage return. It is capped at a measure now.
 *
 *   - Section headings were set at line-height 1.00, so descenders in a
 *     two-line heading sat on the line below.
 *
 *   - The eyebrow above each section was the same 16px as the body text it
 *     sat over, which is not a hierarchy.
 *
 *   - Form fields fell back to Roboto, the one face on the page nothing else
 *     uses, because Elementor styles inputs and the theme does not.
 *
 * WHY THE !important
 *
 * Elementor writes per-element CSS keyed to the page and the element id --
 * `.elementor-5 .elementor-element.elementor-element-abc .pxl-item--title` --
 * which is four classes of specificity aimed at one widget. A layer that
 * tunes those values cannot outrank them by being more specific without
 * naming every element on every page, which is the maintenance burden this
 * file exists to avoid. The declarations that have to beat Elementor's own
 * are marked; nothing else here is.
 *
 * LOADED AFTER THE THEME, by mu-plugins/tecnomation-site.php.
 */

/* ------------------------------------------------------------------ scale
 *
 * Every size is clamp(min, preferred, max). The max is the value the design
 * already used at desktop; the min is a value that reads on a 375px phone;
 * the vw term carries it smoothly between the two, so there is no width at
 * which the type is a desktop value that happens to be too big.
 *
 * The preferred terms are written as `rem + vw` rather than `vw` alone so
 * that a reader who has set a larger default font size still gets one.
 */
:root {
  /* 34px → 72px. The hero. */
  --tec-t-hero: clamp(2.125rem, 1.2rem + 3.9vw, 4.5rem);
  /* 28px → 52px. Section headings. */
  --tec-t-h2: clamp(1.75rem, 1.05rem + 2.95vw, 3.25rem);
  /* 22px → 32px. Card and sub-section headings. */
  --tec-t-h3: clamp(1.375rem, 1.05rem + 1.35vw, 2rem);
  /* 18px → 22px. The smallest thing still set as a heading. */
  --tec-t-h4: clamp(1.125rem, 1rem + 0.55vw, 1.375rem);
  /* 16px → 17px. Body copy gains a point on a large screen, no more. */
  --tec-t-body: clamp(1rem, 0.96rem + 0.18vw, 1.0625rem);
  --tec-t-small: 0.9375rem;
  /* The eyebrow, the form label, the footer's small print. */
  --tec-t-label: 0.8125rem;

  --tec-lh-hero: 1.06;
  --tec-lh-head: 1.14;
  --tec-lh-body: 1.65;

  /* The measure, in characters the reader actually sees.
   *
   * `ch` is the advance of a ZERO, not of an average letter, and in Sora a
   * zero is 0.74em -- wide even for a sans. 68ch measured out at 846px here,
   * which is about 113 characters to the line: the cap was set, and it was
   * set past the problem it was meant to solve. 48ch is ~68 real characters
   * in this face.
   *
   * The rem is the second limit, for the same reason consent.css carries
   * one: ch tracks the font if it ever changes, and the rem stops a face
   * with an unusually wide zero from running the measure out anyway. */
  --tec-measure: min(48ch, 40rem);
  --tec-measure-narrow: min(40ch, 33rem);

  /* The side gutter. Nothing may sit closer than this to the screen edge. */
  --tec-gutter: clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);
}

/* --------------------------------------------------------------- headings
 *
 * Matched on the theme's own heading widget rather than on h1/h2/h3, because
 * the theme sets the tag per widget: the same visual rank is an h2 on one
 * page and an h3 on the next, and styling the tag would size them
 * differently for a reason that has nothing to do with the design.
 */
.pxl-heading .pxl-item--title,
.elementor-widget-heading .elementor-heading-title {
  line-height: var(--tec-lh-head) !important;
  /* Headings break where the line is balanced, not where it happens to run
     out. Ignored by browsers that do not have it, which is the correct
     failure: they get the line break they get today. */
  text-wrap: balance;
}

/* The hero. One per page, and it is the only heading set at this size. */
h1.pxl-item--title,
h1.elementor-heading-title,
.pxl-hero .pxl-heading .pxl-item--title {
  font-size: var(--tec-t-hero) !important;
  line-height: var(--tec-lh-hero) !important;
  /* The design tracks the display face in slightly. Kept, expressed in em so
     it scales with the clamp instead of staying at a pixel value chosen for
     72px type. */
  letter-spacing: -0.01em !important;
}

h2.pxl-item--title,
h2.elementor-heading-title {
  font-size: var(--tec-t-h2) !important;
  letter-spacing: -0.01em !important;
}

h3.pxl-item--title,
h3.elementor-heading-title {
  font-size: var(--tec-t-h3) !important;
}

h4.pxl-item--title,
h4.elementor-heading-title,
h5.pxl-item--title,
h5.elementor-heading-title {
  font-size: var(--tec-t-h4) !important;
}

/* ------------------------------------------------------------- body copy
 *
 * Scoped to the text widgets, which exist only on pages Elementor laid out.
 * The policy pages set their own measure and rhythm in consent.css and must
 * not be reached from here.
 */
.elementor-widget-pxl_text_editor,
.elementor-widget-text-editor {
  font-size: var(--tec-t-body);
  line-height: var(--tec-lh-body);
}

.elementor-widget-pxl_text_editor p,
.elementor-widget-text-editor p,
.elementor-widget-pxl_text_editor li,
.elementor-widget-text-editor li {
  font-size: inherit;
  line-height: inherit;
}

/* The measure, applied to the text rather than to its container, so the
   column keeps its width in the grid and only the line length is bounded.
   `max-width` on the paragraph leaves the layout alone. */
.elementor-widget-pxl_text_editor p,
.elementor-widget-text-editor p {
  max-width: var(--tec-measure);
}

/* A text widget sitting in a column narrower than half the row is already in
   a measure; capping it again only makes it ragged. */
.elementor-column[class*="elementor-col-"] .elementor-widget-pxl_text_editor p {
  max-width: min(var(--tec-measure), 100%);
}

/* Centred copy is centred, including its measure. */
.elementor-widget-pxl_text_editor[class*="text-center"] p,
.pxl-text-center .elementor-widget-pxl_text_editor p,
.elementor-widget-pxl_text_editor.text-center p {
  margin-inline: auto;
}

/* ----------------------------------------------------------- the eyebrow
 *
 * "WHO WE ARE", "WHAT WE DO". It was 16px with no tracking, sitting directly
 * above 52px type and beside 16px body copy -- the same size as the thing it
 * was meant to be subordinate to. Smaller, tracked out and set in the weight
 * the theme uses for labels makes it read as a label at every width.
 */
.pxl-heading .pxl-item--subtitle,
.pxl-item--subtitle,
.pxl-heading .sub-title {
  font-size: var(--tec-t-label) !important;
  line-height: 1.4 !important;
  letter-spacing: 0.14em !important;
  font-weight: 600 !important;
  text-transform: uppercase;
}

/* ------------------------------------------------- the numbered services
 *
 * Each service in the "why work with us" list carries an index -- 01, 02,
 * 03 -- as a span positioned absolutely against the right edge of the row.
 * The heading beside it is a normal block, so its line box runs the full
 * width of the row and straight under the number. On the demo the headings
 * were two or three short words and never reached it. "Integrations and
 * CRM" does: at 390px all three headings ran into their own index.
 *
 * The space is reserved rather than the number moved, because the number's
 * position is the design, and a heading that cannot reach it cannot collide
 * with it at any width -- including widths nobody has measured yet.
 */
.body-meta .pxl-item--title {
  padding-right: 3.25rem;
}

/* --------------------------------------------------------------- controls
 *
 * Buttons keep their pill height, which is a design decision, and gain only
 * a size that holds at small widths and a label that does not wrap mid-word.
 */
.pxl-button .btn,
.elementor-button,
button[type="submit"],
input[type="submit"] {
  font-size: clamp(0.9375rem, 0.9rem + 0.2vw, 1.0625rem);
  /* A button narrower than its label is a clipped label. */
  white-space: normal;
  overflow-wrap: break-word;
}

/* Form fields were the one place on the site set in Roboto: Elementor styles
   inputs, the theme does not, and nothing had said otherwise. */
.wp-row-ctf7 input,
.wp-row-ctf7 select,
.wp-row-ctf7 textarea,
.wpcf7 input,
.wpcf7 select,
.wpcf7 textarea {
  font-family: inherit;
  font-size: var(--tec-t-body);
  line-height: 1.5;
  /* iOS zooms the page in when a focused field is under 16px. */
  min-height: 2.75rem;
}

.wpcf7 label {
  font-size: var(--tec-t-small);
  line-height: 1.5;
}

/* -------------------------------------------------- contact details
 *
 * The theme sets text-transform: capitalize on the get-in-touch block. On
 * the demo that block held labels -- "Call Us", "Email Us" -- where
 * capitalising is invisible. It now holds the real details, and capitalising
 * those renders the address as "Support@Tecnomation.Com" and the reply time
 * as "We Reply Within One Business Day".
 *
 * Set on the leaf rather than on the block, so it beats the inherited value
 * without having to find and outrank whichever ancestor carries it.
 */
.pxl-getintouch .pxl-text,
.pxl-getintouch .item-content {
  text-transform: none;
}

/* ---------------------------------------------------------------- footer
 *
 * The footer's sizes are set in the layout, by build-layouts.js, not here.
 * They are per-element values Elementor writes with four classes of
 * specificity, and the only way a stylesheet beats that is !important on
 * every text widget on the site -- which would also overrule the deliberate
 * sizes everywhere else.
 *
 * This block held `.pxl-footer p` rules for one deploy. There is no
 * .pxl-footer element: the footer is a bare <footer> around
 * .footer-elementor-inner, so the rules matched nothing and the leading they
 * claimed to fix stayed at 2.14. A selector that matches nothing is worse
 * than no selector, because it reads as a solved problem.
 */

/* --------------------------------------------------------------- gutters
 *
 * Nothing may touch the edge of the screen. The theme's container handles
 * this at desktop; below its last breakpoint the container goes to 100% and
 * the padding it was relying on goes with it.
 */
@media (max-width: 1024px) {
  .elementor-section.elementor-section-boxed > .elementor-container {
    padding-inline: var(--tec-gutter);
  }
}

/* ---------------------------------------------------- no sideways scroll
 *
 * The decorative rings, the rotating badges and the marquee are positioned
 * outside their sections on purpose. On a phone they are the width of the
 * screen and a few pixels more, and those few pixels are a horizontal
 * scrollbar across the whole site.
 *
 * Clipping the page rather than each decoration keeps every one of them
 * exactly where the design puts it; the only thing lost is the part that was
 * off-screen anyway.
 */
body {
  overflow-x: clip;
}

/* clip has no fallback value, so a browser without it gets the older
   behaviour explicitly rather than nothing. */
@supports not (overflow-x: clip) {
  body { overflow-x: hidden; }
}

/* A long unbroken string -- an email address, a URL in the policy pages, a
   token in a code sample -- must break rather than push the page wide. */
footer a,
.elementor-widget-pxl_text_editor a {
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------ reduced motion
 *
 * The theme animates headings in letter by letter and spins two badges
 * continuously. A reader who has asked for less of that should get the page
 * at rest, not the page mid-animation.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  /* The headings arrive a word at a time, and the way they do it is WOW.js:
     the markup ships with .wow on each run of text, the theme hides it, and
     a scroll observer adds .animated and an inline visibility later. An
     animation reduced to nothing can leave those elements in their starting
     state, which for animate.css is opacity 0 -- a page of invisible
     headings for exactly the reader who asked for less motion.

     These are the classes the theme actually uses. An earlier version of
     this block named .pxl-split-text, which is not one of them, so it
     protected nothing; the page was audited selector by selector against
     the live DOM to find that out. */
  .wow,
  .wow .letter,
  .animated,
  .pxl-text--slide > * {
    visibility: visible !important;
    opacity: 1 !important;
    transform: none !important;
  }
}
