/*
 *  WebMastro
 *
 *  Object-oriented PHP framework for building HTML5 + Bootstrap 5 websites.
 *
 *  Copyright (C) 2018-2026 Marco Mastroddi. All rights reserved.
 *  SPDX-License-Identifier: LicenseRef-Proprietary
 *
 *  Author: Marco Mastroddi <marco.mastroddi(AT)gmail.com>
 *
 *  The framework's own look (docs/GUIDELINES.md D19, D26, D28): the widgets,
 *  and the few classes the Bootstrap layer needs and Bootstrap lacks (hero
 *  heights), so a new Bootstrap release never touches them. Deliberately no
 *  cascade layer: Bootstrap is not layered, so its element rules (a, button)
 *  would win over any layered rule. Widget rules use classes instead, which
 *  beat element rules, and this file loads after Bootstrap; a site overrides
 *  a widget with a more specific selector. The widgets' custom properties
 *  (--wm-*) are never defined here, only read with a default, so a site sets
 *  them once in :root.
 */

/*
 * Masonry (Widget\Masonry): a plain grid without JavaScript; webmastro.js
 * adds .wm-masonry-ready, switches to 1px rows and gives every item the
 * number of rows it needs, so each one goes to the column that frees first.
 */
.wm-masonry {
  --wm-masonry-max-columns: 100;
  display: grid;
  /* at least the column width (or the whole width, if narrower), and wide
     enough that no more than the maximum number of columns fit */
  grid-template-columns: repeat( auto-fill, minmax( max( min( var( --wm-masonry-column, 18rem ), 100% ),
    ( 100% - ( var( --wm-masonry-max-columns ) - 1 ) * var( --wm-masonry-gap, 1rem ) ) / var( --wm-masonry-max-columns ) ), 1fr ) );
  gap: var( --wm-masonry-gap, 1rem );
  align-items: start;

  &.wm-masonry-ready {
    grid-auto-rows: 1px;
    row-gap: 0;
  }

  /* a photo that is the item itself fills its column; images inside other
     content (a logo in a card) keep their own size */
  .wm-masonry-item > img,
  .wm-masonry-toggle > img {
    display: block;
    width: 100%;
    height: auto;
  }
}

.wm-masonry-max-2 { --wm-masonry-max-columns: 2; }
.wm-masonry-max-3 { --wm-masonry-max-columns: 3; }
.wm-masonry-max-4 { --wm-masonry-max-columns: 4; }
.wm-masonry-max-5 { --wm-masonry-max-columns: 5; }
.wm-masonry-max-6 { --wm-masonry-max-columns: 6; }

.wm-masonry-item {
  min-width: 0;
  scroll-margin-top: 2.5rem;
}

.wm-masonry-expanded {
  grid-column: 1 / -1;
}

/* an enlarged photo fits the window: at most as tall as the viewport less
   the space above it (the scroll margin) and the same below, centered */
.wm-masonry .wm-masonry-expanded .wm-masonry-toggle > img {
  width: auto;
  max-width: 100%;
  max-height: var( --wm-masonry-expanded-height, calc( 100dvh - 5rem ) );
  margin-inline: auto;
}

/* inside .wm-masonry: as specific as Bootstrap's [type=button]:not(:disabled), and later */
.wm-masonry .wm-masonry-toggle {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;

  &[aria-expanded="true"] {
    cursor: zoom-out;
  }

  &:focus-visible {
    outline: 3px solid currentcolor;
    outline-offset: 3px;
  }
}

/*
 * Read more with two labels (Bootstrap\ReadMore::setOpenLabel()): the
 * button holds both, the one matching aria-expanded is shown.
 */
[aria-expanded="true"] > .wm-read-more-closed,
[aria-expanded="false"] > .wm-read-more-open {
  display: none;
}

/*
 * Autoplay (Bootstrap\Carousel::setAutoplay()): the stop/start button shows
 * the icon and the label of what pressing it does; webmastro.js sets
 * data-wm-stopped. Above the carousel's previous/next areas.
 */
.wm-autoplay-toggle {
  z-index: 3;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  box-shadow: 0 0 0 2px #fff;

  &:focus-visible {
    outline: 3px solid #fff;
    outline-offset: 2px;
  }

  &[hidden] {
    display: none;
  }

  &[data-wm-stopped] .wm-autoplay-stop,
  &:not( [data-wm-stopped] ) .wm-autoplay-start {
    display: none !important;
  }
}

/*
 * Focus rings (D41) where Bootstrap's own can hardly be seen (WCAG 2.4.7):
 * a navbar link has a 25% blue shadow (1.3:1 on a dark navbar), a carousel
 * arrow only turns less transparent. Around the element in its text color,
 * which contrasts with its background by construction (navbar links); or
 * inside it, white within dark, visible on any background (dropdown items,
 * carousel arrows over photos). As specific as Bootstrap's rules, and later.
 */
.wm-focus-ring:focus-visible {
  outline: 2px solid currentcolor;
  outline-offset: 2px;
  box-shadow: none;
}

.wm-focus-ring-inset:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -2px;
  box-shadow: inset 0 0 0 4px rgb( 33 37 41 );
}

/*
 * Icon list (Bootstrap\IconList): the icon in its own column, so wrapped
 * lines stay aligned after it.
 */
.wm-icon-list > li {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.5em;
  align-items: baseline;
}

/* read by screen readers only */
.wm-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset( 50% );
  white-space: nowrap;
  border: 0;
}

/* read by screen readers only, shown when it gets the focus (the skip link) */
.wm-visually-hidden-focusable:not( :focus ):not( :focus-within ) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset( 50% );
  white-space: nowrap;
  border: 0;
}

/*
 * The framework's own error page (Http\Router, D40), for sites without
 * one of their own: no CSS framework, so its look is all here.
 */
.wm-error-page {
  max-width: 36rem;
  margin: 12vh auto 2rem;
  padding: 0 1rem;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  line-height: 1.5;
  color: rgb( 33 37 41 );
  text-align: center;

  h1 {
    margin: 0 0 0.75rem;
    font-size: 1.75rem;
  }
}

.wm-error-code {
  margin: 0;
  font-size: 5rem;
  font-weight: 700;
  line-height: 1;
  color: rgb( 13 110 253 / 0.25 );
}

.wm-error-home {
  display: inline-block;
  margin-top: 1rem;
  padding: 0.5rem 1.25rem;
  border-radius: 0.375rem;
  background-color: rgb( 13 110 253 );
  color: white;
  text-decoration: none;

  &:hover,
  &:focus-visible {
    background-color: rgb( 10 88 202 );
  }

  &:focus-visible {
    outline: 3px solid rgb( 13 110 253 / 0.5 );
    outline-offset: 2px;
  }
}

.wm-error-details {
  margin-top: 2rem;
  padding: 1rem;
  overflow-x: auto;
  border-radius: 0.375rem;
  background-color: rgb( 0 0 0 / 0.05 );
  font-size: 0.8125rem;
  text-align: left;
  white-space: pre-wrap;
}

/*
 * Counter (Widget\Counter): webmastro.js shows a counting copy of the
 * number, hidden from screen readers, and keeps the final number for them
 * in a .wm-visually-hidden span.
 */
.wm-counter {
  font-variant-numeric: tabular-nums;
}

/*
 * Back to top (Widget\BackToTop): a round button in the bottom right
 * corner with an arrow drawn by CSS; webmastro.js hides it
 * (.wm-back-to-top-hidden) until the page scrolls down. The white ring
 * keeps it visible on dark backgrounds too.
 */
.wm-back-to-top {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1030;
  display: grid;
  place-items: center;
  width: var( --wm-back-to-top-size, 3rem );
  height: var( --wm-back-to-top-size, 3rem );
  border-radius: 50%;
  color: var( --wm-back-to-top-color, #fff );
  background: var( --wm-back-to-top-background, rgb( 33 37 41 / 0.8 ) );
  box-shadow: 0 0 0 2px #fff;
  text-decoration: none;
  transition: opacity 0.3s, visibility 0.3s;

  &::before {
    content: "";
    width: 0.8rem;
    height: 0.8rem;
    border-top: 0.2rem solid currentcolor;
    border-left: 0.2rem solid currentcolor;
    transform: translateY( 0.2rem ) rotate( 45deg );
  }

  &:hover {
    background: var( --wm-back-to-top-hover-background, rgb( 33 37 41 / 1 ) );
  }

  &:focus-visible {
    outline: 3px solid rgb( 33 37 41 );
    outline-offset: 3px;
  }

  &.wm-back-to-top-hidden {
    opacity: 0;
    visibility: hidden;
  }

  @media ( prefers-reduced-motion: reduce ) {
    transition: none;
  }

  @media print {
    display: none;
  }
}

/*
 * Consent (Widget\ConsentBanner, D34): a dark bar fixed at the bottom of the
 * window, above the page but below Bootstrap's modals; "Reject" and "Accept"
 * look the same (the Garante's rule). webmastro.js shows it and, while it
 * shows, sets .wm-consent-open and --wm-consent-height on <html>: the page
 * gets that much room at the bottom, scrolling keeps the focused element
 * above the bar (WCAG 2.4.11) and the back to top button moves up.
 */
.wm-consent {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1040;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding: 0.75rem 3.5rem 0.75rem 1rem;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var( --wm-consent-color, #fff );
  background: var( --wm-consent-background, rgb( 33 37 41 ) );
  box-shadow: 0 -0.25rem 1rem rgb( 0 0 0 / 0.2 );

  &[hidden] {
    display: none;
  }

  a {
    color: inherit;
    text-decoration: underline;
  }

  a:focus-visible,
  button:focus-visible {
    outline: 3px solid currentcolor;
    outline-offset: 2px;
  }

  @media print {
    display: none;
  }
}

.wm-consent-text {
  flex: 1 1 20rem;
  margin: 0;
}

.wm-consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.wm-consent-button {
  min-width: 7rem;
  padding: 0.375rem 1rem;
  font: inherit;
  color: var( --wm-consent-button-color, rgb( 33 37 41 ) );
  background: var( --wm-consent-button-background, #fff );
  border: 1px solid var( --wm-consent-button-background, #fff );
  border-radius: 0.375rem;
  cursor: pointer;

  &:hover {
    text-decoration: underline;
  }

  .wm-consent &:focus-visible {
    outline-color: var( --wm-consent-color, #fff );
  }
}

/* at least 24 x 24 CSS pixels (WCAG 2.5.8), here 2.75rem */
.wm-consent-close {
  position: absolute;
  top: 0.25rem;
  right: 0.25rem;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  font-size: 1.75rem;
  line-height: 1;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

/* the "Cookie preferences" button looks like a link of the text around it */
.wm-consent-preferences {
  padding: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  background: none;
  border: 0;
  cursor: pointer;
}

.wm-consent-open {
  scroll-padding-bottom: var( --wm-consent-height, 0px );

  body {
    padding-bottom: var( --wm-consent-height, 0px );
  }

  .wm-back-to-top {
    bottom: calc( var( --wm-consent-height, 0px ) + 1rem );
  }
}

/*
 * Charts (Widget\ColumnChart, Widget\BarList): one measure in one color,
 * --wm-chart-color (a blue by default; a site sets its own in :root), on a
 * recessive grid. The SVG stretches to the width (preserveAspectRatio
 * none), its height set here; lines keep one pixel whatever the stretch.
 */
.wm-column-chart {
  margin: 0;
}

.wm-chart-plot {
  display: block;
  width: 100%;
  height: var( --wm-chart-height, 9rem );
  overflow: visible;
}

.wm-chart-bar {
  fill: var( --wm-chart-color, rgb( 13 110 253 ) );

  &:hover {
    fill: var( --wm-chart-hover-color, rgb( 10 88 202 ) );
  }
}

.wm-chart-grid,
.wm-chart-base {
  stroke: var( --wm-chart-grid-color, rgb( 0 0 0 / 0.15 ) );
  stroke-width: 1;
}

.wm-chart-base {
  stroke: var( --wm-chart-axis-color, rgb( 0 0 0 / 0.4 ) );
}

.wm-chart-max,
.wm-chart-axis {
  font-size: 0.8125rem;
  color: var( --wm-chart-text-color, rgb( 33 37 41 / 0.75 ) );
}

.wm-chart-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 0.25rem;
}

.wm-chart-table {
  margin-top: 0.5rem;
  font-size: 0.875rem;

  table {
    margin-top: 0.5rem;
  }

  th,
  td {
    padding: 0.125rem 1rem 0.125rem 0;
  }

  td {
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
}

.wm-bar-list {
  width: 100%;
  border-collapse: collapse;

  caption {
    caption-side: top;
    font-weight: 700;
    color: inherit;
  }

  th,
  td {
    padding: 0.25rem 0.5rem 0.25rem 0;
    border-bottom: 1px solid var( --wm-chart-grid-color, rgb( 0 0 0 / 0.1 ) );
    vertical-align: middle;
  }

  tbody th {
    font-weight: 400;
    overflow-wrap: anywhere;
  }
}

.wm-bar-list-graph {
  width: 40%;
}

.wm-bar-list-bar {
  display: block;
  width: 100%;
  height: 0.625rem;

  rect {
    fill: var( --wm-chart-color, rgb( 13 110 253 ) );
  }
}

.wm-bar-list-number {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/*
 * World map (Widget\WorldMap): the same --wm-chart-color in five shades,
 * mixed with a pale land color; countries without data stay land. The map
 * keeps its proportions (the SVG's viewBox) and the width of its column.
 */
.wm-world-map {
  margin: 0;
}

.wm-map-plot {
  display: block;
  width: 100%;
  height: auto;
}

.wm-map-country {
  fill: var( --wm-map-land-color, rgb( 0 0 0 / 0.08 ) );
  stroke: var( --wm-map-border-color, rgb( 255 255 255 ) );
  stroke-width: 0.4;
  stroke-linejoin: round;

  &:hover {
    stroke: var( --wm-chart-axis-color, rgb( 0 0 0 / 0.6 ) );
    stroke-width: 1;
  }
}

.wm-map-level-1 { fill: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 20%, white ); }
.wm-map-level-2 { fill: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 40%, white ); }
.wm-map-level-3 { fill: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 60%, white ); }
.wm-map-level-4 { fill: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 80%, white ); }
.wm-map-level-5 { fill: var( --wm-chart-color, rgb( 13 110 253 ) ); }

.wm-map-legend {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  color: var( --wm-chart-text-color, rgb( 33 37 41 / 0.75 ) );
  font-variant-numeric: tabular-nums;
}

.wm-map-swatches {
  display: flex;

  span {
    width: 1.5rem;
    height: 0.75rem;
    background-color: var( --wm-map-swatch );
  }

  .wm-map-level-1 { --wm-map-swatch: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 20%, white ); }
  .wm-map-level-2 { --wm-map-swatch: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 40%, white ); }
  .wm-map-level-3 { --wm-map-swatch: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 60%, white ); }
  .wm-map-level-4 { --wm-map-swatch: color-mix( in srgb, var( --wm-chart-color, rgb( 13 110 253 ) ) 80%, white ); }
  .wm-map-level-5 { --wm-map-swatch: var( --wm-chart-color, rgb( 13 110 253 ) ); }
}

/*
 * Hero heights (Bootstrap\HeroHeight), the legacy jumbotron sizes: a
 * share of the screen height; svh does not jump when the address bar of a
 * phone browser shows or hides (vh for older browsers).
 */
.wm-hero-small {
  min-height: 25vh;
  min-height: 25svh;
}

.wm-hero-medium {
  min-height: 40vh;
  min-height: 40svh;

  @media ( max-width: 575.98px ) {
    min-height: 30vh;
    min-height: 30svh;
  }
}

.wm-hero-large {
  min-height: 70vh;
  min-height: 70svh;

  @media ( max-width: 575.98px ) {
    min-height: 60vh;
    min-height: 60svh;
  }
}

/*
 * Separator (Widget\Separator), also used for <hr> inside a Prose: the
 * legacy short line fading at both ends.
 */
.wm-separator,
.wm-prose hr {
  width: 50%;
  height: 2px;
  margin: 3rem auto;
  border: 0;
  background: linear-gradient( to right, transparent, var( --wm-separator-color, #adb5bd ), transparent );
  opacity: 1;
}

/*
 * Prose (Widget\Prose): long texts, with a wider line spacing and emphasized
 * words in the color the site chooses.
 */
.wm-prose {
  line-height: 1.8;

  strong {
    color: var( --wm-prose-emphasis, inherit );
  }
}

/*
 * Quotation (Widget\Quotation), the legacy blockquote: large italic serif
 * text between big grey marks, drawn as generated content with an empty
 * text alternative ("/ \"\""), so screen readers do not announce them
 * (browsers without that syntax keep the first declaration).
 */
.wm-quotation {
  margin: 0;

  blockquote {
    margin: 0;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1.5rem;
    font-style: italic;
    line-height: 1.6;
    quotes: "\201C" "\201D";

    @media ( max-width: 575.98px ) {
      font-size: 1.25rem;
    }

    > p:last-child {
      margin-bottom: 0;
    }

    > p:first-child::before,
    > p:last-child::after {
      position: relative;
      font-size: 2em;
      font-style: normal;
      line-height: 0;
      color: var( --wm-quotation-marks-color, #adb5bd );
    }

    > p:first-child::before {
      content: open-quote;
      content: open-quote / "";
      top: 0.4em;
      margin-right: 0.1em;
    }

    > p:last-child::after {
      content: close-quote;
      content: close-quote / "";
      top: 0.5em;
      margin-left: 0.05em;
    }
  }

  figcaption {
    margin-top: 1rem;
    font-size: 1rem;
    opacity: 0.75;

    &::before {
      content: "\2014\00A0";
    }
  }
}
