/* ==========================================================================
   housduck.com.tw — site.css
   Loaded after style.css. Contains: responsive fixes, accessibility fixes,
   and styles for the components added during the cleanup.
   ========================================================================== */

/* ================================================================ layout
   SITE WIDTH STANDARD — 1200px
   One measure for the header, every content section and the footer, on
   every page. Bootstrap capped .container at 1140px and let
   .container-fluid run the full viewport, so the home carousel row and
   the header/footer disagreed with each other by 300px+.

   Bootstrap's native gutters are left untouched (15px container padding,
   -15px .row margin, 15px column padding) so a .row child and a plain
   child inside the same container still line up on the exact same edge.
   Change --hd-max-width in one place to move the whole site.
   ===================================================================== */

.container,
.container-fluid {
    width: 100%;
    max-width: var(--hd-max-width);
    margin-right: auto;
    margin-left: auto;
}

/* the 4 breakpoint steps Bootstrap ships would otherwise win on specificity */
@media (min-width: 576px) { .container { max-width: var(--hd-max-width); } }
@media (min-width: 768px) { .container { max-width: var(--hd-max-width); } }
@media (min-width: 992px) { .container { max-width: var(--hd-max-width); } }
@media (min-width: 1200px) { .container { max-width: var(--hd-max-width); } }

:root {
    --hd-max-width: 1200px;      /* site width standard — see block above */
    --hd-red: #b3272d;
    --hd-dark: #1c1c1c;
    --hd-muted: #6f6f6f;
    --hd-line: rgba(0, 0, 0, .1);   /* hairline dividers inside a surface */
    --hd-card-line: #e0e0e0;        /* outline of a card / box on the page */
    --hd-radius: 12px;
}

html { -webkit-text-size-adjust: 100%; }

body {
    font-family: "Noto Sans TC", "Roboto", "Microsoft JhengHei", "PingFang TC", sans-serif;
    overflow-x: hidden;           /* FIX: sideways scroll from full-bleed rows */
}

img, svg, iframe, video { max-width: 100%; }
img { height: auto; }

/* Keyboard focus was invisible on the dark theme */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 3px solid var(--hd-red);
    outline-offset: 2px;
}

.pxp-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 1100;
    padding: 12px 20px;
    background: #fff;
    color: #000;
}
.pxp-skip-link:focus { left: 0; }

/* --------------------------------------------------------------- header
   FIX: the old markup used col-2/col-sm-8 for the nav, which left the
   desktop menu squeezed into a 2-column box between 768px and 991px while
   the hamburger was already hidden — no usable navigation in that range.
   The nav column is now shown only from lg up, matching the 991px
   breakpoint the mobile CSS in style.css actually uses.
   -------------------------------------------------------------------- */
.pxp-nav-col { display: none; }

@media (min-width: 992px) {
    .pxp-nav-col { display: block; }
    .pxp-header-nav-trigger { display: none !important; }
}

.pxp-header-nav-trigger {
    background: none;
    color: #000 !important;
    text-decoration: none;
    padding: 10px;
    border: 1px solid #000 !important;
    border-radius: 50%;
    display: inline-block;
    width: 40px;
    height: 40px;
    line-height: 18px;
    font-size: .8rem;
    transition: all .2s ease-in-out;
}
.pxp-dark-mode .pxp-header:not(.pxp-is-sticky):not(.pxp-mobile) .pxp-header-nav-trigger {
    color: #fff !important;
    border-color: #fff !important;
}
.pxp-header.pxp-mobile .pxp-header-nav-trigger { color: #000 !important; border-color: #000 !important; }
.pxp-dark-mode .pxp-header.pxp-mobile .pxp-header-nav-trigger { color: #fff !important; border-color: #fff !important; }

/* Open-menu state: lock the page behind the overlay */
body.pxp-nav-open { overflow: hidden; }

@media (max-width: 991px) {
    .pxp-nav { padding-top: 100px; }
    .pxp-nav > li {
        display: block;
        width: 100%;
        margin: 0;
        padding: 0 24px;
    }
    .pxp-nav > li > a {
        display: block;
        padding: 16px 0;
        font-size: 1.15rem;
        border-bottom: 1px solid rgba(128, 128, 128, .25);
    }
    /* the underline hover effect overlapped the text on touch screens */
    .pxp-nav > li > a:after { display: none; }
}

.pxp-nav > li > a.pxp-active { font-weight: 700; }
.pxp-nav > li > a.pxp-active:after { width: 100%; }

.pxp-logo img { max-height: 40px; width: auto; }

/* ----------------------------------------------------------------- hero */
.pxp-hero.vh-50 { min-height: 420px; }
.pxp-hero-sub { font-size: 1.05rem; opacity: .9; }

.pxp-page-hero {
    position: relative;
    min-height: 320px;
    display: flex;
    align-items: flex-end;
    padding-bottom: 48px;
    margin-top: 0;
    background-position: center;
    background-size: cover;
}
.pxp-page-hero .pxp-hero-opacity {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .55);
}
.pxp-page-hero-caption { position: relative; z-index: 2; }
.pxp-page-hero-caption h1 { margin-bottom: .25rem; }

@media (max-width: 575px) {
    .pxp-hero.vh-50 { min-height: 340px; }
    .pxp-hero-caption h1 { font-size: 1.6rem; line-height: 1.4; }
    .pxp-page-hero { min-height: 220px; padding-bottom: 32px; }
    .pxp-page-hero-caption h1 { font-size: 1.7rem; }
}

/* --------------------------------------------------------------- spacing
   FIX: mt-100 / pt-100 were fixed 100px on every screen, which ate most of
   a phone viewport. Scaled down below 768px.
   -------------------------------------------------------------------- */
@media (max-width: 767px) {
    .mt-100 { margin-top: 56px !important; }
    .pt-100 { padding-top: 56px !important; }
    .pb-100 { padding-bottom: 56px !important; }
    .mb-100 { margin-bottom: 56px !important; }
}

.pxp-section-h2 { line-height: 1.4; }
.pxp-section-sub { font-size: 1.1rem; font-weight: 400; opacity: .75; }
@media (max-width: 575px) {
    .pxp-section-h2 { font-size: 1.5rem; }
    .pxp-section-sub { display: block; font-size: .95rem; margin-top: .25rem; }
    .pxp-page-header { font-size: 1.9rem; }
}

.pxp-note {
    background: rgba(179, 39, 45, .08);
    border-left: 3px solid var(--hd-red);
    padding: 14px 18px;
    border-radius: 6px;
    font-size: .95rem;
}

/* ------------------------------------------------------------- products */
.pxp-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
/* style.css ships its own .pxp-filter-btn from the original theme: a dark
   uppercase box with height:46px, line-height:46px, margin-right:2% and a
   white :hover colour. Three of those leak through and have to be answered
   here:
     - height + line-height fought the padding below, so the label rendered
       ~10px under the middle of the pill instead of centred in it;
     - margin-right:2% stacked on top of the flex `gap`, so the row read as
       unevenly spaced;
     - :hover only set border-color here, so `color` fell through to
       style.css's rgba(255,255,255,.7) — white text on the #F7F7F7 page,
       i.e. the label vanished on mouse-over.
   ------------------------------------------------------------------- */
.pxp-filter-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    height: auto;                /* was a fixed 46px from style.css */
    min-height: 44px;            /* touch target */
    line-height: 1.4;            /* was 46px, which pushed the label down */
    margin: 0;                   /* .pxp-filters `gap` owns the spacing */
    border: 1px solid var(--hd-card-line);
    background: #fff;
    color: var(--hd-dark);
    border-radius: 999px;
    padding: 9px 20px;
    font-size: .95rem;
    cursor: pointer;
    transition: all .18s ease-in-out;
}
.pxp-filter-btn:hover,
.pxp-filter-btn:focus-visible {
    border-color: var(--hd-red);
    color: var(--hd-red);        /* was inheriting white — unreadable */
    background: rgba(179, 39, 45, .06);
    text-decoration: none;
}
.pxp-filter-btn.pxp-active,
.pxp-filter-btn.pxp-active:hover {
    background: var(--hd-red);
    border-color: var(--hd-red);
    color: #fff;
}

.pxp-prod-col { margin-bottom: 24px; }
/* FIX: the card carried `border: 1px solid rgba(0,0,0,.1)` but the
   `.pxp-dark-mode` rule under it repainted that border white at 12% alpha —
   and every page sets class="pxp-dark-mode" on a body whose background is
   the light #F7F7F7. The outline was therefore invisible, and the
   rgba(255,255,255,.03) fill was indistinguishable from the page. The card
   now sits on white behind a real border. */
.pxp-prod {
    display: flex;
    flex-direction: column;
    padding: 24px;
    border: 1px solid var(--hd-card-line);
    background: #fff;
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.pxp-prod:hover {
    transform: translateY(-4px);
    border-color: rgba(179, 39, 45, .35);
    box-shadow: 0 14px 30px rgba(0, 0, 0, .12);
}
.pxp-prod-cat {
    display: inline-block;
    font-size: .75rem;
    letter-spacing: .08em;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(179, 39, 45, .12);
    color: var(--hd-red);
    margin-bottom: 10px;
}
.pxp-prod-name { font-size: 1.25rem; margin: 0 0 12px; }
.pxp-prod-desc {
    font-size: .93rem;
    line-height: 1.85;
    opacity: .85;
    flex: 1 1 auto;
    margin-bottom: 18px;
}
.pxp-prod-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    border-top: 1px solid var(--hd-line);
    padding-top: 16px;
}
.pxp-prod-price { font-size: .9rem; opacity: .8; }
.pxp-prod-price strong { font-size: 1.3rem; }
.pxp-prod-btn {
    border: 0;
    border-radius: 999px;
    background: var(--hd-red);
    color: #fff;
    padding: 10px 22px;
    font-size: .92rem;
    cursor: pointer;
    transition: opacity .18s;
    min-height: 44px;            /* touch target */
}
.pxp-prod-btn:hover { opacity: .85; }
.pxp-empty-msg { padding: 60px 0; text-align: center; opacity: .7; }

/* --------------------------------------------------------------- pieces */
.pxp-prose p { font-size: 1.02rem; line-height: 2.05; margin-bottom: 1.5rem; text-align: justify; }
.pxp-quote {
    border-left: 4px solid var(--hd-red);
    padding: 18px 24px;
    font-size: 1.3rem;
    font-weight: 500;
}
.pxp-stat {
    border: 1px solid var(--hd-card-line);
    padding: 22px;
    text-align: center;
}
.pxp-stat strong { display: block; font-size: 1.7rem; }
.pxp-stat span { font-size: .9rem; opacity: .75; }

.pxp-step {
    border: 1px solid var(--hd-card-line);
    padding: 28px;
}
.pxp-step-n {
    width: 40px; height: 40px; line-height: 40px;
    border-radius: 50%;
    background: var(--hd-red);
    color: #fff;
    text-align: center;
    font-weight: 700;
    margin-bottom: 14px;
}

.pxp-cta-band {
    border: 1px solid var(--hd-card-line);
    padding: 36px;
}

.pxp-featured-item { padding: 4px; }

/* ---------------------------------------------------------------- contact */
.pxp-map-wrap { line-height: 0; }
.pxp-map-wrap iframe {
    width: 100%;
    height: 420px;
    border: 0;
    display: block;
}
@media (max-width: 767px) { .pxp-map-wrap iframe { height: 280px; } }

.pxp-contact-list li {
    display: flex;
    gap: 16px;
    padding: 16px 0;
    border-bottom: 1px solid var(--hd-line);
    line-height: 1.9;
}
.pxp-contact-list .fa { font-size: 1.2rem; color: var(--hd-red); width: 24px; padding-top: 4px; }

.pxp-info-card {
    border: 1px solid var(--hd-card-line);
    padding: 28px;
}
.pxp-info-card p:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------ 404 */
.pxp-404 .pxp-page-header { font-size: 5rem; line-height: 1; }

/* --------------------------------------------------------------- footer */
.pxp-footer-h {
    font-size: .95rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    opacity: .7;
    margin-bottom: .5rem;
}
.pxp-footer-address { font-style: normal; line-height: 2; }
.pxp-footer-base {
    border-top: 1px solid rgba(128, 128, 128, .25);
    font-size: .85rem;
    opacity: .7;
}

/* ---------------------------------------------------------- legal pages
   /terms/ and /privacy/. Two columns inside the same 1200px container
   the rest of the site uses: a sticky in-page index on the left, the text
   on the right, capped so the lines stay readable at full width.
   -------------------------------------------------------------------- */
.pxp-legal-toc {
    position: sticky;
    top: 120px;
}
.pxp-legal-toc ul a {
    font-size: .92rem;
    line-height: 1.7;
    opacity: .8;
}
.pxp-legal-toc ul a:hover { opacity: 1; }
.pxp-legal-date {
    font-size: .85rem;
    opacity: .6;
    padding-top: 14px;
    border-top: 1px solid rgba(128, 128, 128, .25);
}

@media (max-width: 991px) {
    .pxp-legal-toc { position: static; }
}

.pxp-legal { max-width: 820px; }
.pxp-legal h2 {
    font-size: 1.3rem;
    font-weight: 700;
    margin-top: 2.75rem;
    margin-bottom: 1rem;
    scroll-margin-top: 110px;      /* the header is fixed */
}
.pxp-legal h2:first-of-type { margin-top: 0; }
.pxp-legal .pxp-legal-lead {
    font-size: 1.08rem;
    line-height: 2;
    padding-bottom: 1.5rem;
    margin-bottom: 2.5rem;
    border-bottom: 1px solid rgba(128, 128, 128, .25);
    text-align: left;
}
.pxp-legal-address {
    font-style: normal;
    line-height: 2.1;
    font-size: 1.02rem;
}

/* --------------------------------------------------------- footer legal */
.pxp-footer-legal .list-inline-item:not(:last-child) { margin-right: 1.25rem; }

/* --------------------------------------------------------- link contrast
   FIX: style.css line 56 sets a bare `a { color: white }`. Every plain
   inline link therefore rendered white on the light content and footer
   backgrounds — invisible, not just low-contrast. Present on index,
   contact, products and 404 before the legal pages were added.

   Only unclassed body-copy links and the footer address block are
   retargeted here; the nav, hero, CTA and footer-nav links already carry
   their own colour rules and keep them.
   -------------------------------------------------------------------- */
main a:not([class]),
.pxp-footer-address a {
    color: var(--hd-red);
    text-decoration: underline;
    text-underline-offset: .18em;
}
main a:not([class]):hover,
.pxp-footer-address a:hover { opacity: .7; }

/* the in-page index is navigation, so it reads without underlines */
.pxp-legal-toc a { text-decoration: none; }

/* ------------------------------------------------------------ cart drawer
   FIX: the drawer was a 250px slideReveal panel with a hard-coded 230px
   button and absolutely-positioned trigger offsets that fell off-screen on
   small phones. It is now a flex column that adapts, capped at 92vw.
   -------------------------------------------------------------------- */
#slider {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 330px;
    max-width: 92vw;
    background: #f2f2f2;
    color: #1c1c1c;
    z-index: 1050;
    display: flex;
    flex-direction: column;
    padding: 24px 20px 96px;
    box-shadow: -6px 0 24px rgba(0, 0, 0, .18);
    transform: translateX(100%);
    transition: transform .3s ease;
    overflow: visible;
}
#slider.pxp-cart-open { transform: translateX(0); }

/* FIX: the tab was pinned at top:96px — the exact bottom edge of the ~100px
   fixed header — so it collided with the header and, on the inner pages, with
   the top of the page hero. Its count badge hung off the top-LEFT corner, half
   outside the tab. It is now vertically centred on the right edge, which stays
   clear of the header and the footer in both the open and closed states, with
   the icon and the badge aligned inside it. */
#trigger {
    position: absolute;
    top: 50%;
    left: -56px;
    transform: translateY(-50%);
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 10px 0 0 10px;
    background: #d9d9d9;
    box-shadow: -2px 0 10px rgba(0, 0, 0, .12);
    cursor: pointer;
}
#trigger img { display: block; width: 30px; height: 30px; }
#trigger #list-count {
    position: absolute;
    top: 4px;
    right: 4px;
    font-size: .7rem;
}
.pxp-calculator-view {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}
.pxp-cart-empty { opacity: .6; font-size: .92rem; }
.pxp-cart-cta {
    position: absolute;
    left: 20px;
    right: 20px;
    bottom: 24px;
    width: auto;               /* was a fixed 230px */
    text-align: center;
}
#slider .card { border-radius: 8px; }
#slider .btn-link { white-space: normal; text-align: left; padding-left: 0; }

@media (max-width: 575px) {
    #trigger { width: 48px; height: 48px; left: -48px; }
    #trigger img { width: 26px; height: 26px; }
}

/* --------------------------------------------------------------- tables */
.table-responsive { -webkit-overflow-scrolling: touch; }
@media (max-width: 767px) {
    table { font-size: .9rem; }
}

/* ------------------------------------------------------- media / embeds
   FIX: the YouTube embeds were fixed 420x315 and overflowed phones.
   -------------------------------------------------------------------- */
.pxp-video-embed {
    position: relative;
    width: 100%;
    padding-top: 56.25%;
    overflow: hidden;
    border-radius: var(--hd-radius);
}
.pxp-video-embed iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* -------------------------------------------------------------- forms */
.pxp-contact-form .form-control { min-height: 46px; }
@media (max-width: 575px) {
    .pxp-contact-form-btn, .pxp-primary-cta { width: 100%; text-align: center; }
    .pxp-cart-cta { width: auto; }
}
label.error { color: var(--hd-red); font-size: .85rem; display: block; margin-top: 4px; }

/* ------------------------------------------------------------- motion */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

/* -------------------------------------------------------------- print */
@media print {
    .pxp-header, #slider, .pxp-footer, .pxp-hero, .pxp-page-hero { display: none !important; }
    body { color: #000; background: #fff; }
}
