/* ==========================================================================
   mm-radlin.katowice.opoka.org.pl — Phase 1 fixes
   Mobile foundations + correctness.

   HOW TO USE
     Save as  /theme/Boom/css/fixes.css
     Add one line to the page <head>, AFTER responsive.css:
         <link href="/theme/Boom/css/fixes.css" rel="stylesheet" type="text/css">

   WHY A SEPARATE FILE
     Every change here is in one place and can be reverted by deleting one
     <link> tag. Nothing in the original theme is modified, so a CMS theme
     update will not conflict with it.

   Each block is labelled with the audit finding it fixes (AUDIT.md).
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. M1 — Cookie banner must stop covering the site header and logo
   --------------------------------------------------------------------------
   plugins/cbcookies/cbcookies.css sets:
       #cbcookies-top { position: fixed; top: 0; width: 100%; z-index: 9999 }
   Measured: banner occupies y=0..81, the logo occupies y=35..86 — so the
   banner hides the logo completely until the visitor clicks "Akceptuję".

   Fix: anchor the notice to the BOTTOM of the viewport instead of the top.
   It stays unmissable and auto-dismissing, but covers the footer rather
   than the parish's identity.

   The plugin already ships a #cbcookies-bottom rule; we are restyling the
   element the CMS actually renders (#cbcookies-top) to sit at the bottom.  */

#cbcookies-top {
    top: auto;
    bottom: 0;
    border-top: 4px solid #444;
    border-bottom: 0;
    padding: 10px 15px 13px;
    font-size: 13px;
    line-height: 1.5;
    box-sizing: border-box;
}

/* Comfortable tap target for the accept button (M8: target-size) */
#cbcookies_accept {
    display: inline-block;
    padding: 8px 16px;
    margin-top: 6px;
    border-radius: 4px;
    font-weight: 700;
}

/* Give the banner real padding on narrow screens so it does not fill the
   whole viewport height. */
@media only screen and (max-width: 479px) {
    #cbcookies-top {
        font-size: 12.5px;
        padding: 8px 12px 10px;
    }
}


/* --------------------------------------------------------------------------
   2. M2 — Restore the daily liturgy readings on mobile
   --------------------------------------------------------------------------
   responsive.css lines 137 and 174 contain `.phone{display:none}` inside
   max-width:767px and max-width:479px blocks. Measured: .phone renders
   0x0 with display:none — parishioners on a phone cannot see the day's
   readings, feast or Mass times at all.

   Fix: bring it back, and make the widget stack properly on small screens.
   The !important is required to beat the theme's own !important-free but
   later-cascading rule; the media query keeps our override scoped.        */

@media only screen and (max-width: 767px) {
    .phone {
        display: block !important;
    }
    .top-contact {
        width: 100%;
    }
    #header .col-6,
    #header .col-5 {
        max-width: 100%;
        flex: 0 0 100%;
        width: 100%;
    }
    /* Let the logo sit above the liturgy widget instead of beside it */
    #header .container {
        display: flex;
        flex-direction: column;
    }
    #logo {
        text-align: center;
        margin-bottom: 10px;
    }
    #logo img {
        max-width: 260px;
        height: auto;
    }
}


/* --------------------------------------------------------------------------
   3. M4 — Legible, comfortably-leaded body copy
   --------------------------------------------------------------------------
   responsive.css drops body to font-size:14px / line-height:18px (a 1.29
   ratio) below 960px, and style.css:448 forces
       div.nm_post_content p { text-align: justify }
   Justifying paragraphs full of long Polish street names is what produces
   the rivers of white space in the mobile screenshots.                  */

body {
    font-size: 16px;
    line-height: 1.6;
}

div.nm_post_content p,
.article p {
    text-align: left;
    hyphens: auto;
}

/* The nav <select> is a control, not body copy — keep it compact */
#navigation select {
    font-size: 15px;
}


/* --------------------------------------------------------------------------
   4. M5 — Stop the social bar overlapping content
   --------------------------------------------------------------------------
   The bar is position:fixed with a hardcoded top:200px, so it sits on top
   of the hero image and body text at every viewport. Anchor it to the
   bottom-left, clear of the content, and keep it clear of the cookie
   notice (which now occupies the bottom edge).                          */

.easysocialbar {
    top: auto !important;
    bottom: 16px;
    left: 0;
}

.easysocialbar a {
    width: 44px;
    height: 44px;
}

.easysocialbar a:hover {
    width: 44px; /* the theme grows to 60px on hover, which shifts layout */
}

/* On phones the bar competes with the cookie notice for the bottom edge.
   Hide it below 480px; the links are still in the footer. */
@media only screen and (max-width: 479px) {
    .easysocialbar {
        display: none;
    }
}


/* --------------------------------------------------------------------------
   5. M7/M8 — Nav label and touch targets
   --------------------------------------------------------------------------
   The mobile nav is a bare <select> reading "Wybierz stronę" with no
   associated <label> (Lighthouse: select-name). The sidebar quick-links
   are below the 24px minimum with insufficient spacing (target-size).  */

#navigation select {
    min-height: 44px;
    font-weight: 600;
}

#sidebar .article a,
#sidebar p a,
.sb-links a {
    display: inline-block;
    padding: 6px 2px;
    line-height: 1.4;
}

/* One consistent link colour in the sidebar (was: one red link among
   seven default-coloured siblings — finding D4) */
#sidebar p a,
#sidebar .article a,
.sb-links a {
    color: #1a1a1a;
    text-decoration: underline;
}

#sidebar p a:hover,
#sidebar .article a:hover,
.sb-links a:hover {
    color: #51C6AB;
}

/* Keyboard users get the same underline cue, not just the colour change. */
.sb-links a:focus-visible {
    text-decoration: underline;
}


/* --------------------------------------------------------------------------
   6. Accessibility — focus visibility
   --------------------------------------------------------------------------
   No focus styles exist in the theme at all. Keyboard users currently get
   no indication of where they are.                                  */

a:focus-visible,
select:focus-visible,
button:focus-visible {
    outline: 3px solid #51C6AB;
    outline-offset: 2px;
    border-radius: 2px;
}


/* --------------------------------------------------------------------------
   8. Sidebar — the rebuilt component (see patch/data-prep/components.xml)

   The old sidebar was three sibling blocks with inline styles: a 1.13 MB PNG
   banner, a YouTube iframe that autoplayed muted, and a run of eight
   <p style="display:inline-block"> quick links.

   To be clear about why the iframe went: it did NOT cause horizontal
   overflow. Measured at a real 360 px viewport, the old sidebar reports
   scrollWidth == clientWidth == 360, zero overflow, and the embed itself
   measures 321 px wide. Boom already handles this correctly —
   layout.css:3 sets `iframe, object, embed { max-width: 100% !important }`
   and style.css:477 provides a 16:9 `.video-container`. That was checked
   before concluding anything.

   The embed went for three reasons that do hold up:
     - it autoplayed muted audio/video on every single page view;
     - it pulled roughly a megabyte of YouTube iframe JS onto every page,
       including pages with no interest in the stream;
     - the clickable thumbnail directly above it pointed at the same
       stream, so the two were redundant.
   Replaced by a click-to-play poster, so nothing here is width-dependent
   any more. These rules cover what replaces it.
   ------------------------------------------------------------------------ */

/* Kill the inline gap under the banner image, which otherwise shows as a
   few stray pixels of the page background beneath it. */
.sb-banner {
    display: block;
    margin: 0 0 18px;
}

.sb-banner img {
    display: block;
    width: 100%;
    height: auto;
    border: 0;
}

/* The live-stream block. Structure is:
       div.sb-live  >  a.sb-live-poster  >  img + span.sb-live-label
   A ~10 line inline script in the component replaces that <a> with a real
   YouTube <iframe> when the poster is clicked, so the player only loads for
   visitors who ask for it. See build_sidebar.py for why it is inline.      */

.sb-live {
    display: block;
    margin: 0 0 18px;
}

/* The poster is a link, so it must not look like one. The visible label is
   what tells a visitor it is clickable - a bare image with no affordance was
   the old design's other problem. */
.sb-live-poster {
    display: block;
    text-decoration: none;
}

/* Not given a forced aspect ratio. live.png is 592x289, a ratio of 2.05:1 -
   wider than 16:9. An earlier draft pinned it to 16:9 with object-fit:cover
   on the guess that the file was 480x270, which would have cropped ~13% off
   the width and taken out the left-hand area where the caption sits. The
   width/height attributes reserve the correct box instead. build_sidebar.py
   is the single source of truth for both. */

.sb-live-poster img {
    display: block;
    width: 100%;
    height: auto;
    border: 0;
}

.sb-live-label {
    display: block;
    margin-top: 6px;
    font-size: 14px;
    line-height: 1.4;
    font-weight: 600;
    color: #1a1a1a;
}

.sb-live-poster:hover .sb-live-label,
.sb-live-poster:focus-visible .sb-live-label {
    color: #51C6AB;
    text-decoration: underline;
}

/* The player, injected on click. This IS 16:9, unlike the poster: it has to
   be, because that is the shape of the video. The small height change when
   the swap happens is user-initiated and happens once. */
.sb-live iframe {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    border: 0;
}

/* Quick links. Was eight <p style="display:inline-block"> in a row, which
   wrapped unpredictably and gave a ragged right edge. A real list gives
   predictable stacking and a proper document outline.

   The `li` selector is load-bearing, not redundant. Boom's own style.css:93
   has `ul li { list-style : disc outside; }`, and list-style-type INHERITS.
   Setting `list-style:none` on the <ul> alone does nothing visible, because
   every <li> still has its own `disc` specified directly, which beats any
   inherited value. The <ul> reports `none` when queried while the bullets
   render regardless — so measure the <li>, not the <ul>. */
/* Boom styles `#sidebar h3` (style.css:339) but has no rule at all for an
   h2 in the sidebar, so the heading falls back to the browser default and
   came out at 18px against the theme's own h3 sizing. Set it here. */
.sb-links h2 {
    margin: 0 0 10px;
    font-size: 20px;
    line-height: 1.3;
    font-weight: 700;
    color: #1a1a1a;
}

.sb-links ul,
.sb-links ul li {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* One item per line below 768 px; two columns once there is room, so the
   block does not become a tall column of nine lone words.
   The 479 px breakpoint is where the theme switches to its phone layout, but
   the tap-target rule has to start higher than that: measured at a 500 px
   viewport the inline-flex links are only 26 px tall, which clears WCAG 2.2
   2.5.8 (24 px) but not the 44 px that 2.5.5 asks for. */
.sb-links ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0 18px;
}

.sb-links li {
    flex: 1 0 auto;
}

@media only screen and (max-width: 767px) {
    .sb-links ul {
        display: block;
    }
    .sb-links a {
        /* Full-width tap target on a phone — 44 px minimum. */
        display: block;
        padding: 11px 0;
    }
}


/* --------------------------------------------------------------------------
   9. Accessibility — remaining Lighthouse failures
   --------------------------------------------------------------------------
   Added 2026-09-28 after re-measuring production (HANDOFF.md §4). Two of the
   five remaining failures were ours to fix; see the notes on each.         */

/* Kill the 202 px of horizontal scroll on a phone.
   style.css:252 gives #content `display: inline-block`, which makes it a
   shrink-to-fit box — and an inline-block never shrinks below its MIN-CONTENT
   width. Inside it, the news posts are one long run-on paragraph strung
   together with &nbsp; entities, which cannot be broken, so min-content is
   540 px. The page then cannot go below 540 px wide, whatever the viewport.

   Measured against live production at a 360 px viewport: scrollWidth 547 in a
   345 px viewport, i.e. 202 px of sideways scroll, and post headings and body
   text visibly cut off on the right.

   Capping the box is enough — no overflow-wrap needed, because this file
   already sets hyphens:auto on the content paragraphs and the html element
   now carries lang="pl", so the browser has hyphenation points to break at.
   Verified: overflow 202 -> 0 at 360 px, and a no-op at 768 px and 1280 px
   where #content measures 720 and 1140 px either way. */
#content {
    max-width: 100%;
}

/* A heading for the content region, so the document reads h1 -> h2 -> h3
   instead of jumping h1 -> h3 (GetSimple core emits post titles as <h3>).
   The clip technique, NOT display:none — a display:none heading is removed
   from the accessibility tree and would fail the audit it is meant to pass. */
.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Colour contrast on the niedziela.pl widget's date/title line.
   Lighthouse measured 2.09:1 - the parish teal #51C6AB on white, failing the
   4.5:1 that WCAG AA requires for text this size (12.8px).

   #267361 is the same hue (166 degrees) and saturation, darkened to the
   lightest lightness that clears the threshold: 5.66:1 on white. It is still
   recognisably the parish teal rather than a different colour.

   The selector needs the extra .phone to outrank the inline <style> block in
   header.inc.php, which sets span.nd_liturgia_skrot_tytul { color:#51C6AB }
   and sits AFTER this stylesheet in the <head> — so equal specificity would
   lose on order alone. */
.phone span.nd_liturgia_skrot_tytul {
    color: #267361;
}


/* Hide the two niedziela.pl badge images in the header.
   They are the "niezbędnik katolika | niedziela" logo and the
   "Czytaj niedzielę w domu / Zamów e-wydanie" advert.

   DO NOT try to do this with `display: none`. It does not work, and it fails
   silently and intermittently, which is worse than not working at all.

   Something on the page force-shows these elements by writing INLINE styles
   onto them at run time — measured on the rendered DOM as

       <p class="nd_liturgia_skrot_baner" style="display: block !important;">
       <a style="display: inline !important;">
       <img ... style="display: inline !important;">

   An inline `!important` beats any stylesheet rule, including another
   `!important` in a <style> block, so `.phone p.nd_liturgia_skrot_baner
   { display: none !important }` loses. Verified: it appeared to work, then
   stopped working across identical page loads.

   The injector only fires at 479 px and below — precisely the phones this
   project cares about — and it is non-deterministic: five identical loads
   gave 2 with the badges hidden and 3 with them forced visible. Its source
   is not in the files we have; it is not the widget itself (its JS contains
   no such rule), and patching setAttribute/style.setProperty caught nothing,
   so it writes the style some other way.

   Fighting it with JavaScript does not work either: whoever writes last
   wins, and a MutationObserver re-applying `display:none` still lost 5/5.

   So this rule deliberately never touches `display`. It collapses the box
   and hides the contents using properties the injector does not write, which
   makes the result independent of who wins the race:

       height/min-height 0   - collapses the block
       overflow hidden        - clips anything that still renders
       visibility hidden      - belt and braces on the child link and image

   Verified 3/3 at 360 px on top of the deployed stylesheet: badges 0 px, and
   the feast date, the readings, the logo, the slider and the sidebar all
   unchanged to the pixel. */

.phone p.nd_liturgia_skrot_baner {
    height: 0 !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    overflow: hidden !important;
    visibility: hidden !important;
}

/* To hide ONLY the e-edition advert and keep the "niezbędnik katolika" link to
   the day's readings, use this instead of the rule above. Needs :has(), which
   every current browser supports:

   .phone p.nd_liturgia_skrot_baner:has(a[href*="e.niedziela.pl"]) { ... }

   Same properties, same reason. Worth checking with the diocese first: the
   e-edition badge is an advert, and the "niezbędnik katolika" one is a
   functional link to the day's readings.                            */


/* --------------------------------------------------------------------------
   7. M6 — Re-enable pinch zoom  (CSS cannot fix this)
   --------------------------------------------------------------------------
   The page ships <meta name="viewport" content="...maximum-scale=1">,
   which blocks pinch-zoom (WCAG 2.1 AA). This MUST be changed in the
   template <head> — it is a meta tag, not CSS:

       -  content="width=device-width, initial-scale=1, maximum-scale=1"
       +  content="width=device-width, initial-scale=1"

   Marked here so it is not forgotten; no CSS rule can override it.
   ========================================================================== */
