/*
Theme Name: OSEP 2026
Theme URI: https://plaimanas.com
Author: Plaimanas DEV
Author URI: https://plaimanas.com
Description: WordPress theme for สำนักงานส่งเสริมวิสาหกิจเพื่อสังคม (OSEP).
Version: 1.0.0
Requires at least: 6.4
Requires PHP: 8.0
Tested up to: 6.7
License: GNU General Public License v2 or later
License URI: LICENSE
Text Domain: osep
*/

/*
The front-end styling lives in assets/css/ (variables, font-scale-engine,
typography, global, iconfont, theme-wp) and is enqueued from inc/enqueue.php.
That's the front-end team's own file — anything the PHP side of the theme
needs from CSS goes here instead, enqueued after it (`osep-style` depends on
`osep-global`), so these rules win on the cascade without a single line of
assets/css/global.css being touched. Each block below says which of its rules
this is standing in for.
*/
.site-footer__copyright a{
  color: inherit;
  text-decoration:none;
}
/* --- Home : overview / CTA background swap ---
   global.css paints .home-overview__media / .home-cta__media with a fixed
   photo. --overview-bg / --cta-bg (set inline in front-page.php from a Meta
   Box field) let a page's own image replace it without restating either
   section's overlay gradient ; left unset, the design's own photo stands. */
.home-overview__media {
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.40) 0%, rgba(0, 0, 0, 0.00) 35.97%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.30) 0%, rgba(0, 0, 0, 0.30) 100%),
    var(--overview-bg, url("assets/images/main-bg-02.png")) lightgray center / cover no-repeat;
}

.home-cta__media {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.90) 0%, rgba(255, 255, 255, 0.00) 60.98%),
    var(--cta-bg, url("assets/images/fullscreen-media.png")) lightgray center top / cover no-repeat;
}

/* --- Stat map : a real Google Map, not the mockup's flat images ---
   Replaces global.css's .stat-map__bg / .stat-map__frame / .stat-map__image
   (one wide background image behind a centred core image) with a single map
   canvas (assets/js/stat-map.js) sized to the same footprint those two images
   had between them. Each pin is a plain button script relocates into the
   map's own overlay pane, positioned with --marker-x / --marker-y — global.css
   already reads those as the marker's position, in pixels from the map now
   rather than percentages of the old static image. */
.stat-map {
  position: relative;
  width: calc(100% - var(--container-gutter) * 2);
  max-width: calc(var(--container-max-width) - var(--container-gutter) * 2);
  /* mobile : the core image's own footprint, 372 / 743 */
  aspect-ratio: 372 / 743;
  margin-top: 1.2rem;
  margin-inline: auto;
}

@media (min-width: 1024px) {
  .stat-map {
    /* desktop : the combined background + core image, 1320 / 743 */
    aspect-ratio: 1320 / 743;
  }
}

.stat-map__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 1.8rem;
  /* shows while the map tiles are still loading */
  background-color: rgb(var(--color-grey-rgb) / 0.08);
}

.stat-map__marker-icon {
  display: block;
  width: 3.2rem;
  height: 3.2rem;
  /* same white outline global.css gives the icon-location fallback, for
     legibility over the map */
  filter: drop-shadow(0 0 0.1rem #fff) drop-shadow(0 0 0.1rem #fff);
}

/* --- Stat map : Google Places Autocomplete ---
   The address field's suggestion panel is Google's own widget now, not the
   mockup's static list global.css used to skin (.form-field__autocomplete-list
   / -option). .pac-container / .pac-item are Google's class names, not ours —
   this carries that same skin over onto the real dropdown. */
.pac-container {
  margin-top: var(--spacing-xs);
  font-family: inherit;
  border: var(--border-width) solid rgb(var(--color-black-rgb) / 0.1);
  border-radius: 2rem;
  box-shadow: 0 0.4rem 1.6rem rgb(var(--color-black-rgb) / 0.08);
}

.pac-item {
  padding: var(--spacing-sm) var(--spacing-lg);
  color: var(--color-blue);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  border-top-color: rgb(var(--color-black-rgb) / 0.1);
}

.pac-item:hover {
  background-color: var(--color-pastel-light-blue);
}

.pac-icon,
.pac-item-query {
  color: inherit;
}

/* --- Rich text ---
   Output of the theme's WYSIWYG fields (bold, headings, bullet and numbered
   lists, images, alignment) — see osep_wysiwyg_rich_field() / osep_rich_text()
   in inc/helpers.php. The bodies that carry it set `white-space: pre-line` for
   plain copy (global.css), which would turn the HTML's own newlines into
   blank lines ; this switches that off and gives paragraphs, headings and
   lists their spacing, mirroring global.css's own .entry-content treatment. */
.rich-text {
  white-space: normal;
}

.rich-text> :first-child {
  margin-top: 0;
}

.rich-text> :last-child {
  margin-bottom: 0;
}

.rich-text p {
  margin: 0 0 1em;
}

.rich-text :is(ul, ol) {
  margin: 0 0 1em;
  padding-left: 1.2em;
}

.rich-text ul {
  list-style-type: disc;
}

.rich-text ol {
  list-style-type: decimal;
}

.rich-text li {
  padding-left: 0.2em;
}

.rich-text li::marker {
  color: var(--color-blue);
}

.rich-text li+li {
  margin-top: var(--spacing-xs);
}

.rich-text :is(ul, ol) :is(ul, ol) {
  margin-top: var(--spacing-xs);
}

.rich-text a {
  text-decoration: underline;
  text-decoration-thickness: var(--text-decoration-thickness);
  text-underline-offset: var(--text-underline-offset);
}

/* Headings inside the copy, matching global.css's .entry-content scale. */
.rich-text :is(h3, h4, h5) {
  margin: 1.6em 0 0.6em;
  font-family: var(--font-primary);
  font-weight: 600;
  letter-spacing: var(--font-heading-letter-spacing);
  text-transform: var(--font-heading-text-transform);
  color: var(--color-blue);
  text-wrap: pretty;
}

.rich-text h3 {
  font-size: var(--font-size-h3);
  line-height: var(--line-height-h3);
}

.rich-text h4 {
  font-size: var(--font-size-h4);
  line-height: var(--line-height-h4);
}

.rich-text h5 {
  font-size: var(--font-size-h5);
  line-height: var(--line-height-h5);
}

/* Images placed through the editor's Add Media button. */
.rich-text img {
  max-width: 100%;
  height: auto;
  border-radius: 1.2rem;
}

.rich-text :is(figure, .wp-caption) {
  margin: 1.6em 0;
  max-width: 100%;
}

.rich-text :is(figcaption, .wp-caption-text) {
  margin-top: var(--spacing-xs);
  font-size: var(--font-size-sub);
  line-height: var(--line-height-sub);
  color: rgb(var(--color-grey-rgb) / 0.7);
}

.rich-text :is(.alignleft, .alignright, .aligncenter) {
  display: block;
  margin-inline: auto;
}

/* --- ITA archive : the mockup's ITA page, drawn from Gutenberg output ---
   archive-cpt_ita.php shows one post per tab and hands its editor content
   straight to .entry-content, so the mockup's hand-built structure maps onto
   the blocks the editor actually writes :

     the panel's own <h2>  → .ita-year__title
     h4.wp-block-heading   → .ita-group__title   (group heading)
     h5.wp-block-heading   → .ita-subgroup__label
     ol.wp-block-list > li → .ita-item__title    (a numbered disclosure item)
     that li's nested ul   → .ita-item__children / .ita-item__child
     hr.wp-block-separator → the hairline each .ita-group closed with

   All of it scoped to .document-layout__content, so a normal page's
   .entry-content — which global.css lays out as a standalone page — is left
   alone, and so are the download-list archives sharing this same layout. */

/* That standalone-page block is exactly what has to come off here : the panel
   already sits inside .container and the layout's own column. */
.document-layout__content .entry-content {
  max-width: none;
  margin-inline: 0;
  padding: 0;
}

/* The year title. document-archive.php keeps its own heading screen-reader
   only, hence :not(.sr-only). */
.document-layout__content [data-document-section]>h2:not(.sr-only) {
  margin: 0 0 calc(var(--spacing-xl) - 0.5rem);
  color: var(--color-blue);
}

/* Group heading → its items. The :not(:empty) pair is there to out-specify
   global.css's own heading-to-copy gap, which is written the same way. */
.document-layout__content .entry-content h4:not(:empty)+:is(ol, ul, .wp-block-list):not(:empty):not(:first-child) {
  margin-top: calc(var(--spacing-xl) - 0.5rem);
}

/* Subgroup label : greyed back, indented to the items it introduces. */
.document-layout__content .entry-content h5 {
  padding-left: 2.4rem;
  color: rgb(var(--color-grey-rgb) / 0.5);
}

.document-layout__content .entry-content h5:not(:first-child) {
  margin-top: calc(var(--spacing-xl) - 0.5rem);
}

.document-layout__content .entry-content h5:not(:empty)+:is(ol, ul, .wp-block-list):not(:empty):not(:first-child) {
  margin-top: calc(var(--spacing-md) - 0.3rem);
}

/* Disclosure items. `outside` hangs the editor's own numbering in the indent
   instead of running it inline, so wrapped Thai titles stay aligned — and the
   `start` values the editor writes keep one sequence across the groups. */
.document-layout__content .entry-content :is(ol, ol.wp-block-list) {
  padding-left: 2.4rem;
  list-style-position: outside;
}

.document-layout__content .entry-content>:is(ol, ol.wp-block-list)>li {
  color: var(--color-blue);
  font-size: var(--font-size-h5);
  line-height: var(--line-height-h5);
  font-weight: 600;
}

.document-layout__content .entry-content>:is(ol, ol.wp-block-list)>li:not(:first-child) {
  margin-top: calc(var(--spacing-lg) - 0.5rem);
}

.document-layout__content .entry-content>:is(ol, ol.wp-block-list)>li::marker {
  color: inherit;
}

/* Sub-items : a step further in, back to body copy, blue on hover. */
.document-layout__content .entry-content li>:is(ul, ul.wp-block-list) {
  padding-left: 2.4rem;
  margin-top: var(--spacing-sm);
  margin-bottom: calc(var(--spacing-xl) - 0.5rem);
}

.document-layout__content .entry-content li>:is(ul, ul.wp-block-list)>li {
  color: rgb(var(--color-grey-rgb) / 0.7);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  font-weight: 400;
  transition: color var(--duration) var(--easing);
}

.document-layout__content .entry-content li>:is(ul, ul.wp-block-list)>li:not(:first-child) {
  margin-top: var(--spacing-sm);
}

.document-layout__content .entry-content li>:is(ul, ul.wp-block-list)>li:hover {
  color: var(--color-blue);
}

/* A link takes its item's colour rather than global.css's blue-on-everything,
   the way .ita-item__title-link / .ita-item__child-link did. */
.document-layout__content .entry-content li a:not(.wp-block-button__link) {
  color: inherit;
}

.document-layout__content .entry-content>:is(ol, ol.wp-block-list)>li>a:not(.wp-block-button__link):hover {
  color: var(--color-grey);
}

.document-layout__content .entry-content li>:is(ul, ul.wp-block-list)>li a:not(.wp-block-button__link):hover {
  color: var(--color-blue);
}

/* The hairline each group closed with : the editor writes it as a separator
   block, so the group's rhythm is that block's own margins. */
.document-layout__content .entry-content .wp-block-separator:not(:first-child) {
  margin-top: calc(var(--spacing-xl) - 0.3rem);
}

.document-layout__content .entry-content .wp-block-separator+*:not(:first-child) {
  margin-top: calc(var(--spacing-xl) - 0.3rem);
}

/* --- Form Template : the mockup's form page, drawn from a form plugin ---
   template-form.php hands the box the page's own content, so the form is a
   shortcode's output rather than the mockup's hand-written <form>. Contact
   Form 7 writes markup the form's own editor controls — so the fields already
   carry .form-row / .form-field / .form-field__control — but two things it
   adds on its own still need bridging to what global.css styles :

     .wpcf7-form                stands in for .form-report-form
     autop's <p> … <br>         wraps every label + control, which would
                                otherwise sit inside .form-field's flex column
                                instead of being spaced by it

   All scoped to .form-report-page__box, so a form anywhere else on the site
   keeps whatever styling it already has. (Turning CF7's autop off would drop
   the <p> rules below — worth doing if these forms are always hand-written.) */
.form-report-page__box .wpcf7-form {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
}

/* The autop wrapper steps out of the box tree, so the label and the control
   become the flex items .form-field is already spacing. */
.form-report-page__box .wpcf7-form p {
  display: contents;
}

.form-report-page__box .wpcf7-form br {
  display: none;
}

/* CF7 wraps each control in a span of its own — it carries the field's full
   width so .form-field__control's own 100% still resolves against the field. */
.form-report-page__box .wpcf7-form-control-wrap {
  display: block;
  width: 100%;
}

/* Submit, the way global.css centres .form-report-form .btn. */
.form-report-page__box .wpcf7-form .btn {
  align-self: center;
  width: 100%;
  font-family: inherit;
}

@media (min-width: 1024px) {
  .form-report-page__box .wpcf7-form .btn {
    width: auto;
  }
}

/* --- Pagination ---
   osep_pagination() (inc/template-tags.php) hands off to the WP-PageNavi
   plugin when it's active — theme-wp.css already styles that plugin's own
   .wp-pagenavi markup — and falls back to WordPress's own
   the_posts_pagination() otherwise, which theme-wp.css was never written for
   (nothing in it targets .page-numbers). Not installing a plugin just to get
   a look this theme can give its own pagination directly : this carries the
   exact same circles-only treatment over onto WordPress's markup, so the two
   are indistinguishable whichever one is actually rendering. */
.pagination .nav-links {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.8rem;
}

/* .wp-pagenavi hides its prev/next the same way — only the numbers show. */
.pagination .prev.page-numbers,
.pagination .next.page-numbers {
  display: none;
}

.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;

  min-width: 4rem;
  height: 4rem;
  margin: 0;
  padding: 0;

  border: var(--border-width) solid rgb(var(--color-black-rgb) / 0.1);
  border-radius: 50%;

  background-color: var(--color-white);
  color: var(--color-blue);
  text-decoration: none;
  font-size: var(--font-size-h4);
  line-height: var(--line-height-h4);
  font-weight: var(--font-weight-bold);
  opacity: 1;

  transition: background-color var(--duration) var(--easing),
    border-color var(--duration) var(--easing),
    color var(--duration) var(--easing);
}

/* the "…" between distant page numbers — a circle same as the rest, no border
   since it isn't a link */
.pagination .page-numbers.dots {
  border-color: transparent;
}

.pagination a.page-numbers:hover {
  border-color: var(--color-blue);
}

.pagination .page-numbers.current {
  background-color: var(--color-blue);
  border-color: var(--color-blue);
  color: var(--color-white);
}

/* --- Card archive : AJAX fetch in flight ---
   A filter / pagination click on home.php or archive-cpt_media.php replaces
   the whole results block at once (assets/js/main.js, "Card archive"
   handler) rather than animating individual cards out and in the way the
   mockup's own show/hide did (global.css's .media-cards .card.is-filtering-out
   — dormant now, nothing sets that class anymore, but that's global.css's own
   rule to retire, not this file's). This is the coarser stand-in : a plain
   crossfade on the swap itself. */
[data-card-archive-results] {
  transition: opacity 0.2s ease;
}

[data-card-archive-results].is-loading {
  opacity: 0.4;
}

/* --- Single : cpt_media, more than one video ---
   .media-single (global.css) has no gap of its own between children — it
   never needed one, since a post only ever had at most one .media-single__gallery
   block (a video or a gallery, never several of either). The videos tab is
   a repeatable group now (inc/fields/cpt-media.php), so a post can have
   several video blocks back to back ; this is only what keeps consecutive
   ones from touching. */
.media-single__gallery + .media-single__gallery {
  margin-top: var(--spacing-md);
}

/* --- Single : cpt_media, a YouTube embed ---
   .media-single__main (global.css) is aspect-ratio 9/5, sized for the video
   FILE player's own controls bar — a YouTube embed is always 16:9, so this
   overrides just that one property for it, on top of the same block. */
.media-single__main--youtube {
  aspect-ratio: 16 / 9;
}

.media-single__main--youtube iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

/* --- Contact Us : a real Google Map, not the mockup's iframe embed ---
   global.css's .map-container already fills a plain <iframe> child
   (.map-container>iframe { width/height: 100% }) — the map's own canvas is
   a <div> instead (assets/js/contact-map.js draws a real google.maps.Map
   into it, with a real, themed pin rather than an <iframe>'s own default
   marker), so it needs that same "fill the box" treatment restated for a
   div. */
.map-container>.map-container__canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* The pin itself and its tooltip (place name + a "get directions" link) —
   a straight copy of global.css's own .stat-map__marker / .stat-map-tooltip*
   treatment under this page's own class names, since page-stat-map.php's
   pins are exactly the design this one is meant to match, just the one
   fixed pin instead of many scattered ones (assets/js/contact-map.js). */
.contact-map__marker {
  position: absolute;
  left: var(--marker-x);
  top: var(--marker-y);
  /* the pin's point sits on the coordinate, not its centre */
  transform: translate(-50%, -100%);
  color: var(--color-blue);
  line-height: 1;
}

.contact-map__marker .icon-location {
  display: block;
  font-size: 3.2rem;
  /* white outline so the pin stays readable over the map */
  text-shadow:
    0 0 0.1rem #fff,
    0.1rem 0 0 #fff,
    -0.1rem 0 0 #fff,
    0 0.1rem 0 #fff,
    0 -0.1rem 0 #fff,
    0.07rem 0.07rem 0 #fff,
    -0.07rem 0.07rem 0 #fff,
    0.07rem -0.07rem 0 #fff,
    -0.07rem -0.07rem 0 #fff;
}

/* JS moves this to <body> and positions it with Floating UI (top by
   default, flipped/shifted when the viewport is too tight), so the map's
   own overflow never clips it — same as .stat-map-tooltip. */
.contact-map-tooltip {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 90;
  width: min(28rem, calc(100vw - 3.2rem));
  padding: 2rem;
  border-radius: 0.8rem;
  background-color: var(--color-blue);
  color: var(--color-white);
  opacity: 0;
  transition: opacity 0.15s ease;
}

.contact-map-tooltip[hidden] {
  display: none;
}

.contact-map-tooltip.is-open {
  opacity: 1;
}

.contact-map-tooltip__inner {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}

.contact-map-tooltip__title {
  margin: 0;
  color: inherit;
}

.contact-map-tooltip__actions .btn {
  width: auto;
  min-width: 9.5rem;
}

.contact-map-tooltip__arrow {
  position: absolute;
  width: 1.2rem;
  height: 1.2rem;
  background-color: inherit;
  transform: rotate(45deg);
}

@media (min-width: 1024px) {
  .contact-map-tooltip {
    width: 24.8rem;
  }
}
