/*
Theme Name: Custom Redesign
Theme URI: https://happyness-services.nl/
Author: Towerweb
Description: Hardcoded custom theme for Happyness Services, built from the static design export (v1.0).
Version: 1.2.1
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: custom-redesign
*/

/* ==========================================================================
   1. Original site CSS (unchanged, from the <style> block of the export)
   ========================================================================== */

html { scroll-behavior:smooth; scroll-padding-top:110px; }
body { margin:0; overflow-x:hidden; font-family:'Figtree',system-ui,sans-serif; -webkit-font-smoothing:antialiased; background:#fff; }
a { color:inherit; text-decoration:none; }
a:hover { color:#c8176a; }
a[data-cta] > span:first-child { transition:background .25s ease; }
a[data-cta]:hover > span:first-child { background:rgba(255,255,255,0.55); }
input, textarea { font-family:'Figtree',system-ui,sans-serif; max-width:100%; }
* { box-sizing:border-box; }
img { max-width:100%; }

/* ==========================================================================
   2. Hover states
   The export carried these as style-hover="..." attributes, which only the
   design-canvas runtime understood. They are now data-hover="..." attributes
   with real :hover rules. !important is required because the base values sit
   in inline style attributes, which otherwise always win.
   ========================================================================== */

[data-hover="pink"]:hover        { background:#e0357f !important; }
[data-hover="pink-pale"]:hover   { background:#fdeaf3 !important; }
[data-hover="tint"]:hover        { background:#fdf5f8 !important; }
[data-hover="tint-border"]:hover { background:#fdf7fa !important; border-color:#e3e3e3 !important; }
[data-hover="white-text"]:hover  { color:#fff !important; }
[data-hover="lift"]:hover        { transform:translateY(-6px) !important; box-shadow:0 24px 54px rgba(30,12,22,0.24) !important; }

/* ==========================================================================
   3. Navigation — breakpoint 900px
   The export swapped the desktop and mobile navigation in JavaScript
   (isDesktop / isMobile, w > 900). Both are now in the markup; CSS decides.

   900.02px rather than 901px: viewport widths can be fractional (browser
   zoom, some device pixel ratios). At 900.5px both "max-width:900px" and
   "min-width:901px" are false, which would leave the page with no navigation
   at all.
   ========================================================================== */

.hs-nav-desktop,
.hs-nav-toggle,
.hs-mobile-panel { display:none !important; }

@media (min-width:900.02px) {
  .hs-nav-desktop { display:flex !important; }
}

@media (max-width:900px) {
  .hs-nav-toggle { display:flex !important; }
  .hs-mobile-panel.is-open { display:flex !important; }
}

/* Desktop "Diensten" dropdown. Was menuO/menuY/menuV/menuP in JS state; the
   transition itself is still inline on the element, so only the end states
   are needed here. :focus-within keeps it reachable by keyboard. */
.hs-dropdown {
  opacity:0;
  transform:translateY(-8px);
  visibility:hidden;
  pointer-events:none;
}
.hs-caret { transform:rotate(0deg); }

@media (min-width:900.02px) {
  .hs-has-dropdown:hover        > .hs-dropdown,
  .hs-has-dropdown:focus-within > .hs-dropdown {
    opacity:1;
    transform:translateY(0);
    visibility:visible;
    pointer-events:auto;
  }
  .hs-has-dropdown:hover        .hs-caret,
  .hs-has-dropdown:focus-within .hs-caret { transform:rotate(180deg); }
}

/* ==========================================================================
   4. Accordions — mobile submenu and FAQ
   Both animate an open/closed state that used to live in JS (grid-template-
   rows 0fr/1fr, an opacity fade and a rotating "+"). assets/js/theme.js now
   toggles .is-open and CSS does the rest; all transitions stay inline.
   ========================================================================== */

.hs-anim-grid { grid-template-rows:0fr; }
.hs-anim-grid.is-open { grid-template-rows:1fr; }

.hs-anim-fade { opacity:0; }
.hs-anim-fade.is-open { opacity:1; }

/* The FAQ answer also slides; the submenu does not. */
.hs-faq-fade { transform:translateY(-6px); }
.hs-faq-fade.is-open { transform:translateY(0); }

/* "+" rotates 135deg into a "×". */
.hs-faq-sign,
.hs-sub-sign { transform:rotate(0deg); }
.hs-faq-sign.is-open,
.hs-sub-sign.is-open { transform:rotate(135deg); }

.hs-faq-q,
.hs-sub-toggle { user-select:none; }

/* ==========================================================================
   4b. Viewport-height sizing
   Mobile browsers hide and reveal the address bar while you scroll, which
   changes the viewport height. Anything sized in vh is recalculated as that
   happens, so the homepage hero visibly shrank mid-scroll.

   svh ("small viewport height") is pinned to the viewport with the address
   bar shown, so it does not move. The vh line stays first as a fallback for
   browsers without svh support (pre-2022); browsers that understand svh use
   the second declaration.
   ========================================================================== */

.hs-home-hero {
  min-height:min(78vh,620px);
  min-height:min(78svh,620px);
}

.hs-mobile-panel {
  max-height:78vh;
  max-height:78svh;
}

/* ==========================================================================
   5. Service page hero — breakpoint 760px
   Six values the export computed in JavaScript (heroWrapW, heroWrapPad,
   heroMin, heroAlign, heroPad, heroBgPos) against its own 760px breakpoint,
   which is deliberately NOT the same as the 900px navigation breakpoint.
   ========================================================================== */

.hs-hero-wrap {
  width:min(92%,1440px);
  margin:0 auto;
  padding:0 20px;
}
.hs-hero {
  min-height:min(510px,74vh);
  min-height:min(510px,74svh);
  align-items:center;
  padding:clamp(16px,3vw,36px);
  background-position:center right;
}

@media (max-width:760px) {
  .hs-hero-wrap {
    width:100%;
    padding:0 10px;
  }
  .hs-hero {
    min-height:0;
    align-items:flex-end;
    padding:110px 6px 6px;
    background-position:center top;
  }
}

/* ==========================================================================
   6. WordPress housekeeping
   ========================================================================== */

.admin-bar header[style*="position:sticky"] { top:32px; }
@media screen and (max-width:782px) {
  .admin-bar header[style*="position:sticky"] { top:46px; }
}

/* The WordPress admin bar is 600px wide at minimum, which pushes a phone
   viewport open and makes the site look too wide — for logged-in users only.
   Visitors never see this; this keeps it from misleading you while testing. */
@media screen and (max-width:600px) {
  #wpadminbar { min-width:0 !important; }
}

/* --------------------------------------------------------------------------
   Contact Form 7 inside the offer card.

   The grid, spacing and field styling below reproduce the form that was drawn
   in the design export. It expects the form template documented in the theme
   README: a .hs-form-grid wrapper with one .hs-field div per field. Fields are
   wrapped in divs rather than bare labels because Contact Form 7 runs its own
   auto-paragraph pass over the template, and that pass leaves block-level
   elements alone but wraps inline ones in <p> - which would break the grid.
   -------------------------------------------------------------------------- */

.hs-form-grid {
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,290px),1fr));
  gap:18px 26px;
}

.hs-field--full { grid-column:1 / -1; }

.hs-field label {
  display:flex;
  flex-direction:column;
  gap:8px;
  font-size:14px;
  color:#4a4a4a;
}

/* CF7 wraps every control in an inline span; make it fill the label. */
.hs-field .wpcf7-form-control-wrap { display:block; }

.hs-form-actions { margin-top:24px; }
.hs-form-actions input[type="submit"] { margin-top:0; }

/* Honeypot decoy field. Moved off-screen rather than display:none, because
   better-written bots skip hidden inputs but still fill this one. Sighted and
   screen-reader users never reach it: the wrapper is aria-hidden and the input
   is taken out of the tab order. See custom_redesign_honeypot_spam() in
   functions.php for the matching server-side check. */
.hs-hp {
  position:absolute !important;
  left:-9999px !important;
  top:auto;
  width:1px;
  height:1px;
  overflow:hidden;
}

/* Validation feedback, kept in the site's own pink. */
.wpcf7 .wpcf7-not-valid { border-color:#c8176a !important; }
.wpcf7-not-valid-tip { margin-top:4px; font-size:13px; color:#c8176a; }

.wpcf7 form.wpcf7-form p { margin:0 0 18px; font-size:14px; color:#4a4a4a; }
.wpcf7 input[type="text"],
.wpcf7 input[type="email"],
.wpcf7 input[type="tel"],
.wpcf7 input[type="url"],
.wpcf7 input[type="date"],
.wpcf7 input[type="number"],
.wpcf7 select,
.wpcf7 textarea {
  width:100%; border:1px solid #d8d8d8; border-radius:5px; padding:0 12px;
  font-size:15px; outline:none; background:#fff; color:#1b1b1b;
}
.wpcf7 input[type="text"],
.wpcf7 input[type="email"],
.wpcf7 input[type="tel"],
.wpcf7 input[type="url"],
.wpcf7 input[type="date"],
.wpcf7 input[type="number"],
.wpcf7 select { height:40px; }
.wpcf7 textarea { padding:10px 12px; resize:vertical; min-height:120px; }
.wpcf7 input[type="submit"] {
  margin-top:6px; width:100%; background:#c4166b; color:#fff; border:none;
  border-radius:5px; height:48px; font-size:16px; font-weight:600;
  cursor:pointer; transition:background .25s ease;
}
.wpcf7 input[type="submit"]:hover { background:#e0357f; }
