/*
Theme Name: Hello Elementor Child — Dr Jen Law
Template: hello-elementor
Version: 1.0.0
Description: The ONE stylesheet for drjenlaw. Rules of engagement: class selectors only, no !important, no element IDs,
             nothing that could be expressed in Elementor Site Settings / templates / widget settings instead.
             Every rule states which platform gap it covers. Keep it under 150 lines.
*/

/* Rich text = Elementor text editors AND the blog post content (Theme Builder), so every rule below targets both.
   1. Squarespace zeroes the trailing margin of the last paragraph in a text block; Elementor's kit paragraph
      spacing (1em) applies to every <p>, which silently adds 16px under every text widget. Zero it here so the
      widget margins in the data model are truthful. */
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) :where(p, ul, ol, h1, h2, h3, h4):last-child:not(li *) {
  margin-block-end: 0;
}
/* 1b. Squarespace paragraphs carry 1em above AND below (collapsing to 1em between neighbours); list items are 0.5em
      apart. Reproducing the top margin is what makes headings/lists/paragraphs collapse the way live does. */
/* 1c. Squarespace rich text is white-space: pre-wrap (every <p>, <li>, heading carries it inline): preserved spaces count at line
      ends, so lines break earlier than with normal white-space — measurably different paragraph heights on narrow columns. */
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content, .elementor-tab-content) :is(p, h1, h2, h3, h4) { white-space: pre-wrap; } /* not li: WordPress wraps list items in newlines, and Squarespace list text is inside <p> anyway */
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) p { margin-block-start: 1rem; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) :is(ul, ol) { margin-block: 1rem; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) li > p { margin-block: 0 0.5rem; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) li > p:last-child { margin-block-end: 0.5rem; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) :where(p, ul, ol, h2, h3, h4):first-child,
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) :is(img, figure):first-child + :where(p, ul, ol, h2, h3, h4) { margin-block-start: 0; }

/* 2. Logo marquee. Squarespace runs a continuous scroller (custom code on live); Elementor has no marquee element,
      so the markup lives in an HTML widget (.jl-marquee) and the motion lives here. Live: 80px logos, 100px apart,
      44px logos on phones. */
.jl-marquee { overflow: hidden; width: 100%; }
.jl-marquee-track { display: flex; align-items: center; width: max-content; animation: jl-scroll 40s linear infinite; }
.jl-marquee-track img { height: 80px; width: auto; margin: 0 50px; flex: none; }
@media (max-width: 767px) { .jl-marquee-track img { height: 44px; margin: 0 25px; } }
@keyframes jl-scroll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .jl-marquee-track { animation: none; } }

/* 3. Footer Instagram tiles are SQUARE crops on live (263×263 @1920; the 4:5 source is centre-cropped). Elementor's
      image widget has no aspect-ratio control, so the ratio lives here (grid, gaps and order are in the template). */
.jl-ig .elementor-widget-image img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
.jl-ig .elementor-widget-image a { display: block; } /* the linked tile is an inline-block anchor otherwise (6px descender gap) */

/* 4. Header nav must be allowed to wrap when the row is too narrow (live wraps "CONTACT" at 1280). A flex item's
      min-width defaults to its content width, so without this the row overflows the gutter instead of wrapping. */
.e-con > .elementor-widget-nav-menu { min-width: 0; }

/* 5. Live shows no focus rectangle on mouse/touch activation (menu items, buttons); keep the ring for keyboard users. */
a:focus:not(:focus-visible), button:focus:not(:focus-visible) { outline: none; }

/* 6. Squarespace rich-text conventions that Elementor has no control for. Values come from the kit's CSS variables,
      never hardcoded here.
      - inline image floated right inside a text block (About bio) — Elementor containers are flex, so a float only
        works inside the text widget's own content
      - .sqsrte-large = "Paragraph 1", .sqsrte-small = "Paragraph 3"; .sqsrte-text-color--* = the three brand text colours
      - headings inside rich text sit 2rem from the copy above and below (live: h2/h4 margin 32px) */
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) .jl-float-right { float: right; width: 40.5%; height: auto; margin: 0 0 16px 17px; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) .jl-float-right.jl-col-6 { width: calc(50% - 17px); margin-block-end: 0; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) figure.jl-float-right { margin-inline: 34px 0; } /* image block: 17px padding each side → 34px between text and photo */
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) figure.jl-float-right figcaption { margin-block-start: 16px; }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) figure.jl-float-right img { width: 100%; height: auto; object-fit: cover; } /* the crop ratio comes from the img's own aspect-ratio (Squarespace block ratio) */ /* a col-6 image block floated in a full-width text block */
@media (max-width: 767px) {
  :is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) .jl-float-right { float: none; width: 100%; margin: 0 0 16px; }
  :is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) .jl-float-right.jl-col-6 { width: 100%; margin-block-end: 34px; } /* stacked image block: 17px + 17px block padding */
}
.sqsrte-large { font-size: var(--e-global-typography-p1-font-size); line-height: var(--e-global-typography-p1-line-height); letter-spacing: var(--e-global-typography-p1-letter-spacing); }
.sqsrte-small { font-size: var(--e-global-typography-small09-font-size); line-height: var(--e-global-typography-small09-line-height); }
.sqsrte-text-color--darkAccent { color: var(--e-global-color-secondary); }
.sqsrte-text-color--lightAccent { color: var(--e-global-color-lightnude); }
.sqsrte-text-color--accent { color: var(--e-global-color-accent); }
:is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) :is(h2, h3, h4) { margin-block: 2rem; }
/* headings inside a text block take the block's text colour (Squarespace section themes colour headings and text alike — e.g. the
   "bright" theme is black on tan); the kit heading colours stay for stand-alone heading widgets. */
body :is(.elementor-widget-text-editor, .elementor-widget-theme-post-content) :is(h1, h2, h3, h4) { color: inherit; }

/* 7. Accordion = Elementor Toggle widget styled as the Squarespace accordion block (procedure.js toggleWidget):
      the +/- is a 24px cross drawn with 1px lines in the text colour (Elementor's icon fonts are heavy and have no size control),
      a 1px rule sits above the first item as well as under each item, and the description is Squarespace rich text at n0.9:
      paragraphs 0 / 1rem, lists flush, list paragraphs 0.5em apart, nothing under the last block. */
.elementor-toggle .elementor-tab-title { position: relative; line-height: normal; } /* Squarespace: the title line-height is the font's normal (Marcellus ≈1.254, rounded per line) */
.elementor-toggle .elementor-tab-title .elementor-toggle-title { display: block; padding-inline-end: 48px; line-height: normal; } /* live: title padding-right 24 + 24px icon → every line wraps at width − 48; (0,3,0) beats the widget default line-height */
/* the icon: a 24px box centred on the title (live's flex button), two 24×1 bars in the text colour; the vertical one is the horizontal
   bar rotated 90°, and it rotates back to 0° over 0.25s when the item opens — exactly Squarespace's plus→minus interaction */
.elementor-toggle .elementor-tab-title .elementor-toggle-icon { position: absolute; inset-inline-end: 0; top: 50%; translate: 0 -50%; width: 24px; height: 24px; margin: 0; }
.elementor-toggle .elementor-tab-title .elementor-toggle-icon :is(i, svg), .elementor-toggle .elementor-tab-title.elementor-active .elementor-toggle-icon :is(i, svg) { display: none; } /* Elementor's opened glyph carries .elementor-toggle-icon-opened itself → (0,4,1) needed */
.elementor-toggle .elementor-tab-title .elementor-toggle-icon::before, .elementor-toggle .elementor-tab-title .elementor-toggle-icon::after { content: ""; position: absolute; inset: 12px 0 auto 0; height: 1px; background: currentColor; }
.elementor-toggle .elementor-tab-title .elementor-toggle-icon::after { rotate: 90deg; transition: rotate 0.25s; }
.elementor-toggle .elementor-tab-title.elementor-active .elementor-toggle-icon::after { rotate: 0deg; }
.elementor-toggle .elementor-toggle-item:first-child > .elementor-tab-title { border-block-start: 1px solid; }
.elementor-toggle .elementor-tab-content p { margin-block: 0 1rem; }
.elementor-toggle .elementor-tab-content :is(ul, ol) { margin-block: 0; }
.elementor-toggle .elementor-tab-content li > p { margin-block: 0 0.5em; }
.elementor-toggle .elementor-tab-content > :last-child { margin-block-end: 0; }

/* 8. Pro Form: an HTML field is a group title ("Name" above First / Last name) and sits on the fields below it like a
      label — its spacing comes from the widget's HTML Field > Spacing control, not from the row gap. */
.elementor-widget-form .elementor-form .elementor-form-fields-wrapper .elementor-field-group.elementor-field-type-html { margin-block-end: 0; } /* (0,5,0): outranks the widget's own row-gap rule without !important */

/* 9. Blog. List pagination: Squarespace shows only the available direction ("Older Posts"); Elementor renders the other one
      as a disabled placeholder. Prev/next post titles wrap like live (Elementor truncates them to one ellipsised line) and sit on
      a 1.0 line-height as the live item-pagination titles do. */
.elementor-pagination .page-numbers.disabled { display: none; }
.elementor-post-navigation :is(.post-navigation__prev--title, .post-navigation__next--title) { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1; }

/* 10. Aftercare lock screen (Elementor template "drjen-lock-screen", rendered by mu-plugins/drjen-aftercare.php while page 7 is
       locked). The password form is the one piece Elementor can't build: the native <form> posting to wp-login.php?action=postpass.
       Squarespace lock field = 280×44 white, 14px, 2px ink outline offset 4px, 48×44 arrow inside; colours from the kit. */
.jl-lock { position: relative; width: 280px; max-width: 100%; margin-inline: auto; }
.jl-lock input { box-sizing: border-box; width: 100%; height: 44px; padding: 14px 63px 14px 15px; border: 0; border-radius: 0; background: #fff; box-shadow: none; outline: 2px solid var(--e-global-color-lockink); outline-offset: 4px; font: 14px/14px Arial, "Helvetica Neue", sans-serif; letter-spacing: 0.7px; color: var(--e-global-color-lockink); transition: none; }
.jl-lock input::placeholder { color: #bababa; opacity: 1; }
.jl-lock input:focus-visible { outline-color: #000; box-shadow: none; }
.jl-lock button, .jl-lock button:is(:hover, :focus) { position: absolute; inset: 0 0 auto auto; width: 48px; height: 44px; padding: 0; border: 0; border-radius: 0; background: none; color: inherit; line-height: 0; cursor: pointer; }
.jl-lock svg { width: 48px; height: 44px; fill: var(--e-global-color-lockink); }
.jl-lock-error { margin: 16px 0 0; text-align: center; font: 14px/1.3 Arial, "Helvetica Neue", sans-serif; letter-spacing: 0.7px; color: var(--e-global-color-lockink); }

/* 11. Header shrink on scroll (Squarespace, below 800px only): the fixed header's 6vw vertical padding drops to 21.6px (768–799)
       / 16.24px (≤767) once the page is scrolled 20px+. Elementor's sticky adds .elementor-sticky--effects past its Effects Offset. */
@media (max-width: 799px) {
  .elementor-location-header > .e-con > .e-con-inner { transition: padding 0.2s ease; } /* boxed containers carry their padding on .e-con-inner */
  .elementor-location-header > .e-con.elementor-sticky--effects > .e-con-inner { padding-block: 21.6px; }
}
@media (max-width: 767px) { .elementor-location-header > .e-con.elementor-sticky--effects > .e-con-inner { padding-block: 16.24px; } }

/* 12. Text rasterisation parity. On live, Squarespace's fixed menu overlay forces the whole page onto a composited layer, so
       Chrome on Windows renders every glyph with greyscale anti-aliasing (lighter, thinner-looking text). Elementor's text
       sits in normal flow and gets sub-pixel (LCD) anti-aliasing instead, which reads visibly heavier side by side. Promoting
       each widget to its own layer reproduces live's rendering (49 widgets ≈ 17 MB worst case on the longest page). The
       off-canvas widget is excluded: its overlay is position: fixed and a transformed ancestor would trap it. */
.elementor-widget:not(.elementor-widget-off-canvas) { will-change: transform; }

/* 13. Before/after comparison. Live runs the "Rebecca Grace image slider" (a jQuery plugin loaded from codepen.io — when that
       host is blocked the two photos simply stack). Rebuilt natively: procedure.js wraps the two images in a .jl-compare container,
       functions.php prints the pointer/keyboard script that sets --pos. Left = before, right = after; the plugin's 3px white divider
       and 50px white ring with arrows, both with its 12px shadow. */
.jl-compare { --pos: 50%; position: relative; overflow: hidden; touch-action: pan-y; user-select: none; } /* overflow: the box is the first photo's height; a taller second photo is clipped like live */
.jl-compare img { pointer-events: none; -webkit-user-drag: none; }
.jl-compare > .elementor-widget-image:nth-of-type(2) { position: absolute; inset: 0; clip-path: inset(0 0 0 var(--pos)); }
.jl-compare::before { content: ""; position: absolute; inset: 0 auto 0 calc(var(--pos) - 1.5px); width: 3px; background: #fff; box-shadow: 0 0 12px rgba(51, 51, 51, 0.5); pointer-events: none; }
.jl-compare::after { content: ""; position: absolute; top: 50%; left: var(--pos); width: 50px; height: 50px; translate: -50% -50%; box-sizing: content-box; border: 3px solid #fff; border-radius: 50%; box-shadow: 0 0 12px rgba(51, 51, 51, 0.5); background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 56'%3E%3Cpath fill='%23fff' d='M10 18 0 28l10 10zM36 18l10 10-10 10z'/%3E%3C/svg%3E") center / 56px 56px no-repeat; background-origin: border-box; cursor: pointer; }
.jl-compare:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* 14. Mobile burger. Live draws three 35×1px lines in the text colour, 9.5px apart, inside a 35px box; Elementor's icon widget
       only offers glyph fonts, so its glyph is hidden and the lines are painted on the icon box (colour = the widget's icon colour). */
.jl-burger .elementor-icon { display: block; width: 35px; height: 35px; background: linear-gradient(currentColor 0 0) 0 7.5px / 100% 1px no-repeat, linear-gradient(currentColor 0 0) 0 17px / 100% 1px no-repeat, linear-gradient(currentColor 0 0) 0 26.5px / 100% 1px no-repeat; }
.jl-burger .elementor-icon :is(i, svg) { display: none; }
