UI: kolumna dostępności 6–13.02, sekcja Archiwum, nowy termin w nagłówkach

porownanie.html:
- nowa kolumna „Dostępność 6–13.02” z pola `dostepnosc_6_13_02_2027`,
  skrócona do emoji + werdyktu ( DOSTĘPNE / 🔍 do sprawdzenia /
   BRAK (zweryf.)), pełna notatka w atrybucie title
- sortowanie kolumny układa decyzyjnie (wolne → do sprawdzenia → brak),
  nie alfabetycznie po emoji
- wiersz Glemm Lodge na czerwono i z przekreśloną nazwą: zweryfikowany
  brak miejsc bije kolor statusu ceny (reguła CSS niżej wygrywa)
- karty `priorytet: ARCHIWALNA` wypadają z tabeli i z bilansu do osobnej
  sekcji „Archiwum” na dole strony
- legenda i bilans statusów pod tabelą

Termin wyjazdu wyjechał do stałych TERM_LABEL/TERM_SHORT/TERM_NOTE:
nagłówki wszystkich stron (BUNDLE_NAME, też w gen_viz.py), lead
start.html, opis kafla porównania i raport braków biorą go stąd.
Zmiana terminu = zmiana stałych i regeneracja.

Raport braków czyta teraz dostępność z pola frontmattera zamiast zgadywać
z nagłówków w body, i pomija karty archiwalne. Wypis po regeneracji
podaje bilans /🔍/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
oskar 2026-08-04 10:00:23 +02:00
parent de10b94bd9
commit 06ab1b24aa
24 changed files with 377 additions and 64 deletions

View file

@ -9,9 +9,11 @@ przez pole `resource` (patrz gen_viz.py).
Poza kartą na koncept skrypt generuje trzy strony zbiorcze: Poza kartą na koncept skrypt generuje trzy strony zbiorcze:
pages/index.html spis wszystkich kart, pogrupowany katalogami pages/index.html spis wszystkich kart, pogrupowany katalogami
pages/porownanie.html jedna tabela WSZYSTKICH ofert (nie regionów), pages/porownanie.html jedna tabela WSZYSTKICH aktualnych ofert (nie
sortowalna klikiem, złożona z samych frontmatterów; regionów), sortowalna klikiem, złożona z samych
na górze podsumowanie per region z `wyjazd.md` frontmatterów; na górze podsumowanie per region
z `wyjazd.md`, na dole sekcja Archiwum z kartami
`priorytet: ARCHIWALNA` (riscercz na poprzedni termin)
pages/start.html landing: trzy kafle (porównanie / analiza / graf) pages/start.html landing: trzy kafle (porównanie / analiza / graf)
plus linki do kart czterech regionów plus linki do kart czterech regionów
@ -51,7 +53,12 @@ import yaml
BUNDLE_ROOT = Path(__file__).resolve().parent BUNDLE_ROOT = Path(__file__).resolve().parent
PAGES_DIRNAME = "pages" PAGES_DIRNAME = "pages"
PAGES_DIR = BUNDLE_ROOT / PAGES_DIRNAME PAGES_DIR = BUNDLE_ROOT / PAGES_DIRNAME
BUNDLE_NAME = "Ski 2027 — Skicircus Saalbach" BUNDLE_NAME = "Ski 2027 — wyjazd 613.02.2027"
# Termin wyjazdu w jednym miejscu: leci do nagłówków stron i do raportu
# braków. Zmiana terminu = zmiana tych dwóch stałych i regeneracja.
TERM_LABEL = "613.02.2027"
TERM_SHORT = "613.02" # nagłówek kolumny w tabeli porównawczej
TERM_NOTE = "tydzień Fasching, szczyt sezonu"
RESERVED = {"index.md", "log.md"} RESERVED = {"index.md", "log.md"}
# Publiczny adres wystawki — jedyne miejsce, w którym siedzi domena. Używa go # Publiczny adres wystawki — jedyne miejsce, w którym siedzi domena. Używa go
@ -420,11 +427,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }
@ -870,6 +885,7 @@ def parse_conclusions(text: str) -> list[str]:
# (nagłówek, pole frontmattera / klucz specjalny, czy sortować liczbowo) # (nagłówek, pole frontmattera / klucz specjalny, czy sortować liczbowo)
COLUMNS: list[tuple[str, str, bool]] = [ COLUMNS: list[tuple[str, str, bool]] = [
("Oferta", "_nazwa", False), ("Oferta", "_nazwa", False),
(f"Dostępność {TERM_SHORT}", "_dostepnosc", False),
("Priorytet", "priorytet", False), ("Priorytet", "priorytet", False),
("Region", "_region", False), ("Region", "_region", False),
("Miejscowość", "miejscowosc", False), ("Miejscowość", "miejscowosc", False),
@ -895,6 +911,56 @@ def is_offer(concept: Concept) -> bool:
return str(concept.frontmatter.get("type", "")).startswith("oferta") return str(concept.frontmatter.get("type", "")).startswith("oferta")
# --- dostępność terminu (pole `dostepnosc_6_13_02_2027`) ---------------
AVAILABILITY_FIELD = "dostepnosc_6_13_02_2027"
# (emoji z legendy, skrót do komórki, klucz sortowania). Kolejność kluczy
# układa kolumnę decyzyjnie: potwierdzone wolne → do sprawdzenia → brak.
AVAILABILITY_MARKS = (
("", "✅ DOSTĘPNE", "1"),
("🔍", "🔍 do sprawdzenia", "2"),
("", "❌ BRAK (zweryf.)", "3"),
)
def availability(concept: Concept) -> str:
return str(concept.frontmatter.get(AVAILABILITY_FIELD) or "").strip()
def availability_mark(value: str) -> tuple[str, str, str] | None:
for mark in AVAILABILITY_MARKS:
if value.startswith(mark[0]):
return mark
return None
def _availability_cell(value: str) -> str:
"""Komórka dostępności: emoji + jedno słowo, pełna treść w `title`.
Wartości z frontmattera zdaniami (🔍 BRAK DANYCH silnik online
pokaże od ręki), a tabela ma się skanować wzrokiem więc w komórce
zostaje sam werdykt, a uzasadnienie czeka pod kursorem.
"""
if not value:
return '<td class="avail" data-key="9">—</td>'
mark = availability_mark(value)
if not mark:
return _cell(value, False)
_, short, key = mark
return (
f'<td class="avail" data-key="{key}" '
f'title="{html.escape(value, quote=True)}">{html.escape(short)}</td>'
)
def is_archived(concept: Concept) -> bool:
"""Karty z riserczu na poprzedni termin — poza tabelą i statusami."""
return str(concept.frontmatter.get("priorytet") or "").upper().startswith(
"ARCHIWALNA"
)
def _shorten(value: str) -> str: def _shorten(value: str) -> str:
"""Sam rdzeń wartości; doprecyzowanie w nawiasie/po myślniku idzie do title. """Sam rdzeń wartości; doprecyzowanie w nawiasie/po myślniku idzie do title.
@ -929,29 +995,22 @@ def _cell(value: str, numeric: bool, suffix: str = "", short: bool = True) -> st
return f"<td{attrs}>{html.escape(shown + suffix)}</td>" return f"<td{attrs}>{html.escape(shown + suffix)}</td>"
def render_comparison(concepts: list[Concept], regions: list[Region]) -> str: def _offer_rows(offers: list[Concept], by_dir: dict[str, Region]) -> str:
"""Jedna tabela wszystkich ofert bundle'a, prosto z frontmatterów.""" """Wiersze tabeli porównawczej dla podanych ofert."""
by_dir = {r.dirname: r for r in regions}
offers = [c for c in concepts if is_offer(c)]
# Domyślna kolejność: najtańsza rodzina 2+2 na górze — pierwsze pytanie,
# które grupa zadaje. Resztę porządków daje sortowanie klikiem.
offers.sort(
key=lambda c: (
sort_number(str(c.frontmatter.get("koszt_rodzina_2p2") or "")) or 1e9,
c.title,
)
)
rows = [] rows = []
for concept in offers: for concept in offers:
frontmatter = concept.frontmatter frontmatter = concept.frontmatter
status = str(frontmatter.get("status_ceny") or "") status = str(frontmatter.get("status_ceny") or "")
upper = status.upper() upper = status.upper()
css_row = ( classes = [
"verified" if "ZWERYFIKOWANE" in upper "verified" if "ZWERYFIKOWANE" in upper
else "estimate" if "SZACUNEK" in upper else "estimate" if "SZACUNEK" in upper
else "" else ""
) ]
# Zweryfikowany brak miejsc to najmocniejszy komunikat w wierszu —
# ważniejszy niż to, czy cena jest pewna.
if availability(concept).startswith(""):
classes.append("unavailable")
dirname = posixpath.dirname(posixpath.dirname(concept.id)) dirname = posixpath.dirname(posixpath.dirname(concept.id))
region = by_dir.get(dirname) region = by_dir.get(dirname)
region_label = region.label if region else (dirname or "") region_label = region.label if region else (dirname or "")
@ -984,6 +1043,8 @@ def render_comparison(concepts: list[Concept], regions: list[Region]) -> str:
cells.append( cells.append(
f'<td data-key="{html.escape(region_label, quote=True)}">{shown}</td>' f'<td data-key="{html.escape(region_label, quote=True)}">{shown}</td>'
) )
elif field == "_dostepnosc":
cells.append(_availability_cell(availability(concept)))
elif field == "www": elif field == "www":
url = str(frontmatter.get("www") or "").strip() url = str(frontmatter.get("www") or "").strip()
if url: if url:
@ -1006,18 +1067,66 @@ def render_comparison(concepts: list[Concept], regions: list[Region]) -> str:
cells.append( cells.append(
_cell(value, numeric, suffix, short=field not in NO_SHORTEN) _cell(value, numeric, suffix, short=field not in NO_SHORTEN)
) )
css_row = " ".join(c for c in classes if c)
klass = f' class="{css_row}"' if css_row else "" klass = f' class="{css_row}"' if css_row else ""
rows.append(f"<tr{klass}>{''.join(cells)}</tr>") rows.append(f"<tr{klass}>{''.join(cells)}</tr>")
return "".join(rows)
def _comparison_table(offers: list[Concept], by_dir: dict[str, Region]) -> str:
head = '<th data-key="">Zdjęcie</th>' + "".join( head = '<th data-key="">Zdjęcie</th>' + "".join(
f'<th scope="col" aria-sort="none">{html.escape(title)}</th>' f'<th scope="col" aria-sort="none">{html.escape(title)}</th>'
for title, _, _ in COLUMNS for title, _, _ in COLUMNS
) )
table = ( return (
'<div class="table-wrap"><table class="sortable"><thead><tr>' '<div class="table-wrap"><table class="sortable"><thead><tr>'
f"{head}</tr></thead><tbody>{''.join(rows)}</tbody></table></div>" f"{head}</tr></thead><tbody>{_offer_rows(offers, by_dir)}</tbody>"
"</table></div>"
) )
def _by_price(concept: Concept) -> tuple[float, str]:
# Domyślna kolejność: najtańsza rodzina 2+2 na górze — pierwsze pytanie,
# które grupa zadaje. Resztę porządków daje sortowanie klikiem.
return (
sort_number(str(concept.frontmatter.get("koszt_rodzina_2p2") or "")) or 1e9,
concept.title,
)
def render_comparison(concepts: list[Concept], regions: list[Region]) -> str:
"""Jedna tabela wszystkich aktualnych ofert bundle'a, prosto z frontmatterów.
Karty archiwalne (riscercz na poprzedni termin) idą do osobnej tabeli
na dole strony nie mieszają się do porównania ani do statusów
dostępności, ale nie znikają z bazy.
"""
by_dir = {r.dirname: r for r in regions}
offers = sorted((c for c in concepts if is_offer(c)), key=_by_price)
active = [c for c in offers if not is_archived(c)]
archived = [c for c in offers if is_archived(c)]
table = _comparison_table(active, by_dir)
counts: dict[str, int] = {}
for concept in active:
mark = availability_mark(availability(concept))
counts[mark[1] if mark else ""] = counts.get(mark[1] if mark else "", 0) + 1
tally = " · ".join(f"{label}: {n}" for label, n in sorted(counts.items()))
archive = ""
if archived:
archive = (
'<section class="archive">\n'
"<h2>Archiwum — poza paczką riserczową 08.2026</h2>\n"
f'<p class="lead">Karty z riserczu na poprzedni termin '
f"(1623.01.2027). Ceny i dostępność nie były weryfikowane na "
f"{html.escape(TERM_LABEL)} — nie wchodzą do porównania wyżej ani "
"do statusów dostępności. Zostają, bo tropy są nadal dobre.</p>\n"
f"{_comparison_table(archived, by_dir)}\n"
"</section>"
)
summary = "" summary = ""
if regions: if regions:
items = [] items = []
@ -1042,14 +1151,22 @@ def render_comparison(concepts: list[Concept], regions: list[Region]) -> str:
content = ( content = (
"<h1>Porównanie ofert</h1>\n" "<h1>Porównanie ofert</h1>\n"
f'<p class="lead">Wszystkie {len(offers)} rozważanych noclegów w jednej ' f'<p class="lead">Wszystkie {len(active)} rozważanych noclegów na termin '
"tabeli — dane prosto z frontmatterów kart. Kliknij nagłówek, żeby " f"<strong>{html.escape(TERM_LABEL)}</strong> ({html.escape(TERM_NOTE)}) "
"posortować; domyślnie od najtańszej rodziny 2+2.</p>\n" "w jednej tabeli — dane prosto z frontmatterów kart. Kliknij nagłówek, "
"żeby posortować; domyślnie od najtańszej rodziny 2+2.</p>\n"
f"{summary}\n" f"{summary}\n"
"<h2>Wszystkie oferty</h2>\n" "<h2>Wszystkie oferty</h2>\n"
f"{table}\n" f"{table}\n"
'<p class="legend"><span class="box v"></span>cena zweryfikowana ' '<p class="legend"><span class="box v"></span>cena zweryfikowana '
'&nbsp; <span class="box e"></span>szacunek do potwierdzenia</p>' '&nbsp; <span class="box e"></span>szacunek do potwierdzenia '
'&nbsp; <span class="box u"></span>zweryfikowany brak miejsc<br>'
f"Dostępność {html.escape(TERM_SHORT)}: ✅ DOSTĘPNE (zweryfikowane) · "
"🔍 do sprawdzenia (obiekt nie publikuje kalendarza) · "
"❌ BRAK (zweryfikowane). "
f"Bilans: {html.escape(tally)}. Najedź na komórkę, żeby zobaczyć "
"pełną notatkę.</p>\n"
f"{archive}"
) )
return _page_shell( return _page_shell(
"Porównanie ofert", 0, content, body_class="wide", script=SORT_JS "Porównanie ofert", 0, content, body_class="wide", script=SORT_JS
@ -1062,8 +1179,8 @@ def render_comparison(concepts: list[Concept], regions: list[Region]) -> str:
# tylko ścieżki root-absolutne działają pod obiema (patrz docstring modułu). # tylko ścieżki root-absolutne działają pod obiema (patrz docstring modułu).
TILES = [ TILES = [
("/pages/porownanie.html", "Porównanie ofert", ("/pages/porownanie.html", "Porównanie ofert",
"Wszystkie noclegi w jednej sortowalnej tabeli: ceny, status ceny, " "Wszystkie noclegi w jednej sortowalnej tabeli: dostępność na "
"priorytet, odległość od wyciągu."), f"{TERM_SHORT}, ceny, status ceny, priorytet, odległość od wyciągu."),
("/pages/wyjazd.html", "Analiza wariantów", ("/pages/wyjazd.html", "Analiza wariantów",
"Cztery regiony obok siebie: skipassy, dojazd, budżet całkowity grupy " "Cztery regiony obok siebie: skipassy, dojazd, budżet całkowity grupy "
"i wnioski przekrojowe."), "i wnioski przekrojowe."),
@ -1111,7 +1228,8 @@ def render_start(concepts: list[Concept], regions: list[Region]) -> str:
content = ( content = (
f"<h1>{html.escape(BUNDLE_NAME)}</h1>\n" f"<h1>{html.escape(BUNDLE_NAME)}</h1>\n"
'<p class="lead">1623.01.2027, 4 rodziny / 14 osób, wyjazd z Warszawy. ' f'<p class="lead"><strong>{html.escape(TERM_LABEL)}</strong> '
f"({html.escape(TERM_NOTE)}), 4 rodziny / 14 osób, wyjazd z Warszawy. "
"Od czego zacząć:</p>\n" "Od czego zacząć:</p>\n"
f'<ul class="tiles">{tiles}</ul>\n' f'<ul class="tiles">{tiles}</ul>\n'
"<h2>Regiony</h2>\n" "<h2>Regiony</h2>\n"
@ -1383,7 +1501,7 @@ def missing_data(concepts: list[Concept]) -> list[tuple[str, list[str]]]:
"""Czego brakuje w ofertach — bez zgadywania, tylko z tego, co jest.""" """Czego brakuje w ofertach — bez zgadywania, tylko z tego, co jest."""
report = [] report = []
for concept in concepts: for concept in concepts:
if not str(concept.frontmatter.get("type", "")).startswith("oferta"): if not is_offer(concept) or is_archived(concept):
continue continue
gaps = [] gaps = []
status = str(concept.frontmatter.get("status_ceny") or "") status = str(concept.frontmatter.get("status_ceny") or "")
@ -1391,10 +1509,13 @@ def missing_data(concepts: list[Concept]) -> list[tuple[str, list[str]]]:
gaps.append("brak pola `status_ceny`") gaps.append("brak pola `status_ceny`")
elif "SZACUNEK" in status.upper(): elif "SZACUNEK" in status.upper():
gaps.append(f"cena niepotwierdzona ({status})") gaps.append(f"cena niepotwierdzona ({status})")
# Danymi o dostępności jest osobna sekcja (jak w glemm-lodge), a nie # Dostępność czytamy z pola frontmattera, nie z nagłówka w tekście —
# samo słowo w tekście — "duża dostępność" w opisie się nie liczy. # werdykt ✅/❌/🔍 jest danymi, a nie tym, czy ktoś napisał sekcję.
if not re.search(r"^#+\s*.*dostępnoś", concept.body, re.IGNORECASE | re.M): value = availability(concept)
gaps.append("brak danych o dostępności terminu 1623.01.2027") if not value:
gaps.append(f"brak pola `{AVAILABILITY_FIELD}`")
elif value.startswith("🔍"):
gaps.append(f"dostępność {TERM_LABEL} do weryfikacji ({_shorten(value)})")
open_todos = len(re.findall(r"^\s*[-*]\s+\[ \]", concept.body, re.M)) open_todos = len(re.findall(r"^\s*[-*]\s+\[ \]", concept.body, re.M))
if open_todos: if open_todos:
gaps.append(f"otwartych pozycji „Do zrobienia”: {open_todos}") gaps.append(f"otwartych pozycji „Do zrobienia”: {open_todos}")
@ -1458,10 +1579,21 @@ def main() -> int:
f"Regiony z wyjazd.md: {len(regions)} " f"Regiony z wyjazd.md: {len(regions)} "
f"({', '.join(r.label for r in regions) or ''})" f"({', '.join(r.label for r in regions) or ''})"
) )
active = [c for c in offers if not is_archived(c)]
print( print(
f"Oferty w tabeli porównawczej: {len(offers)}, " f"Oferty w tabeli porównawczej: {len(active)} "
f"(+{len(offers) - len(active)} archiwalnych w osobnej sekcji), "
f"ze zdjęciami: {len(with_photos)} (zdjęcia dokłada gen_images.py)" f"ze zdjęciami: {len(with_photos)} (zdjęcia dokłada gen_images.py)"
) )
marks = [availability_mark(availability(c)) for c in active]
print(
f"Dostępność {TERM_LABEL}: "
+ " · ".join(
f"{label}: {sum(1 for m in marks if m and m[1] == label)}"
for _, label, _ in AVAILABILITY_MARKS
)
+ f" · bez pola: {sum(1 for m in marks if m is None)}"
)
gaps = missing_data(concepts) gaps = missing_data(concepts)
print() print()

View file

@ -71,7 +71,7 @@ from urllib.parse import urlsplit, urlunsplit
import yaml import yaml
BUNDLE_ROOT = Path(__file__).resolve().parent BUNDLE_ROOT = Path(__file__).resolve().parent
BUNDLE_NAME = "Ski 2027 — Skicircus Saalbach" BUNDLE_NAME = "Ski 2027 — wyjazd 613.02.2027"
CATALOG = Path(os.environ.get("KNOWLEDGE_CATALOG", "/tmp/knowledge-catalog")) CATALOG = Path(os.environ.get("KNOWLEDGE_CATALOG", "/tmp/knowledge-catalog"))
sys.path.insert(0, str(CATALOG / "okf" / "src")) sys.path.insert(0, str(CATALOG / "okf" / "src"))

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Karty — Ski 2027 — Skicircus Saalbach</title> <title>Karty — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }
@ -149,7 +157,7 @@ td.thumb .placeholder { display: flex; width: 120px; height: 80px; border-radius
</head> </head>
<body> <body>
<nav><a href="start.html">← Start</a> · <a href="index.html">Wszystkie karty</a> · <a href="porownanie.html">Porównanie ofert</a> · <a href="linki.html">Linki</a> · <a href="../viz.html">Graf</a></nav> <nav><a href="start.html">← Start</a> · <a href="index.html">Wszystkie karty</a> · <a href="porownanie.html">Porównanie ofert</a> · <a href="linki.html">Linki</a> · <a href="../viz.html">Graf</a></nav>
<h1>Ski 2027 — Skicircus Saalbach</h1> <h1>Ski 2027 — wyjazd 613.02.2027</h1>
<p class="lead">Karty konceptów bundle'a — pełna treść każdego dokumentu (ceny, dostępność, plusy/minusy). Struktura powiązań: <a href="../viz.html">graf</a>.</p> <p class="lead">Karty konceptów bundle'a — pełna treść każdego dokumentu (ceny, dostępność, plusy/minusy). Struktura powiązań: <a href="../viz.html">graf</a>.</p>
<h2>Wyjazd i wiedza ogólna</h2> <h2>Wyjazd i wiedza ogólna</h2>
<ul class="cards"><li><a href="szablon-maila.html">Szablon zapytania grupowego (EN)</a> <span class="chip">narzedzie</span><p>Gotowy angielski mail o 4 apartamenty dla 14 osób w terminie 613.02.2027, z pytaniem o najbliższy wolny tydzień i notatkami negocjacyjnymi na rynek Fasching.</p></li><li><a href="wyjazd.html">Ski 2027 — cztery warianty na termin 613.02.2027</a> <span class="chip">Trip</span><p>Wyjazd narciarski 4 rodzin (14 osób) z Warszawy w tygodniu Fasching: porównanie czterech regionów, statusy dostępności noclegów i wnioski przekrojowe.</p></li></ul> <ul class="cards"><li><a href="szablon-maila.html">Szablon zapytania grupowego (EN)</a> <span class="chip">narzedzie</span><p>Gotowy angielski mail o 4 apartamenty dla 14 osób w terminie 613.02.2027, z pytaniem o najbliższy wolny tydzień i notatkami negocjacyjnymi na rynek Fasching.</p></li><li><a href="wyjazd.html">Ski 2027 — cztery warianty na termin 613.02.2027</a> <span class="chip">Trip</span><p>Wyjazd narciarski 4 rodzin (14 osób) z Warszawy w tygodniu Fasching: porównanie czterech regionów, statusy dostępności noclegów i wnioski przekrojowe.</p></li></ul>

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apartment Brandau (Kappl) — Ski 2027 — Skicircus Saalbach</title> <title>Apartment Brandau (Kappl) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apartments Kappl — Ski 2027 — Skicircus Saalbach</title> <title>Apartments Kappl — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ischgl / Silvretta Arena + dolina Paznaun — Ski 2027 — Skicircus Saalbach</title> <title>Ischgl / Silvretta Arena + dolina Paznaun — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Häuslerhof (Valdaora) — Ski 2027 — Skicircus Saalbach</title> <title>Häuslerhof (Valdaora) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Residence Corones (Valdaora) — Ski 2027 — Skicircus Saalbach</title> <title>Residence Corones (Valdaora) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kronplatz / Plan de Corones (Południowy Tyrol) — Ski 2027 — Skicircus Saalbach</title> <title>Kronplatz / Plan de Corones (Południowy Tyrol) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Linki — Ski 2027 — Skicircus Saalbach</title> <title>Linki — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

File diff suppressed because one or more lines are too long

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>AlpenParks Apartments Rehrenberg — Ski 2027 — Skicircus Saalbach</title> <title>AlpenParks Apartments Rehrenberg — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>AlpenParks Hotel &amp; Apartment Sonnleiten — Ski 2027 — Skicircus Saalbach</title> <title>AlpenParks Hotel &amp; Apartment Sonnleiten — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Duży dom wakacyjny 1214 os. (do wyszukania) — Ski 2027 — Skicircus Saalbach</title> <title>Duży dom wakacyjny 1214 os. (do wyszukania) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Glemm Lodge Apartments ⭐⭐⭐⭐ — Ski 2027 — Skicircus Saalbach</title> <title>Glemm Lodge Apartments ⭐⭐⭐⭐ — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Appartementhaus Kristall at SchattbergXpress — Ski 2027 — Skicircus Saalbach</title> <title>Appartementhaus Kristall at SchattbergXpress — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sportchalet Viehhofen — Ski 2027 — Skicircus Saalbach</title> <title>Sportchalet Viehhofen — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Skicircus Saalbach-Hinterglemm-Leogang-Fieberbrunn — Ski 2027 — Skicircus Saalbach</title> <title>Skicircus Saalbach-Hinterglemm-Leogang-Fieberbrunn — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apart Ideal (Serfaus) — Ski 2027 — Skicircus Saalbach</title> <title>Apart Ideal (Serfaus) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Haus Central (Apart Central), Ladis — Ski 2027 — Skicircus Saalbach</title> <title>Haus Central (Apart Central), Ladis — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Serfaus-Fiss-Ladis (SFL) — Ski 2027 — Skicircus Saalbach</title> <title>Serfaus-Fiss-Ladis (SFL) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Start — Ski 2027 — Skicircus Saalbach</title> <title>Start — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }
@ -149,9 +157,9 @@ td.thumb .placeholder { display: flex; width: 120px; height: 80px; border-radius
</head> </head>
<body> <body>
<nav><a href="/pages/index.html">Wszystkie karty</a> · <a href="/pages/porownanie.html">Porównanie ofert</a> · <a href="/pages/linki.html">Linki</a> · <a href="/viz.html">Graf</a></nav> <nav><a href="/pages/index.html">Wszystkie karty</a> · <a href="/pages/porownanie.html">Porównanie ofert</a> · <a href="/pages/linki.html">Linki</a> · <a href="/viz.html">Graf</a></nav>
<h1>Ski 2027 — Skicircus Saalbach</h1> <h1>Ski 2027 — wyjazd 613.02.2027</h1>
<p class="lead">1623.01.2027, 4 rodziny / 14 osób, wyjazd z Warszawy. Od czego zacząć:</p> <p class="lead"><strong>613.02.2027</strong> (tydzień Fasching, szczyt sezonu), 4 rodziny / 14 osób, wyjazd z Warszawy. Od czego zacząć:</p>
<ul class="tiles"><li><a href="/pages/porownanie.html">Porównanie ofert<small>Wszystkie noclegi w jednej sortowalnej tabeli: ceny, status ceny, priorytet, odległość od wyciągu.</small></a></li><li><a href="/pages/wyjazd.html">Analiza wariantów<small>Cztery regiony obok siebie: skipassy, dojazd, budżet całkowity grupy i wnioski przekrojowe.</small></a></li><li><a href="/viz.html">Graf powiązań<small>Struktura bazy wiedzy — koncepty, linki między nimi i adresy zewnętrzne. Załącznik, nie punkt wejścia.</small></a></li><li><a href="/pages/linki.html">Wszystkie linki<small>Pełne adresy wszystkich stron wystawki, z przyciskiem „kopiuj” — do wrzucenia grupie.</small></a></li></ul> <ul class="tiles"><li><a href="/pages/porownanie.html">Porównanie ofert<small>Wszystkie noclegi w jednej sortowalnej tabeli: dostępność na 613.02, ceny, status ceny, priorytet, odległość od wyciągu.</small></a></li><li><a href="/pages/wyjazd.html">Analiza wariantów<small>Cztery regiony obok siebie: skipassy, dojazd, budżet całkowity grupy i wnioski przekrojowe.</small></a></li><li><a href="/viz.html">Graf powiązań<small>Struktura bazy wiedzy — koncepty, linki między nimi i adresy zewnętrzne. Załącznik, nie punkt wejścia.</small></a></li><li><a href="/pages/linki.html">Wszystkie linki<small>Pełne adresy wszystkich stron wystawki, z przyciskiem „kopiuj” — do wrzucenia grupie.</small></a></li></ul>
<h2>Regiony</h2> <h2>Regiony</h2>
<p class="lead">Karta regionu = skipassy, dojazd, terminy, koszty życia i budżet całkowity.</p> <p class="lead">Karta regionu = skipassy, dojazd, terminy, koszty życia i budżet całkowity.</p>
<ul class="regions"><li><a href="/pages/saalbach/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/alpenparks-sonnleiten/01.jpg')">Saalbach<small>Budżet grupy: ~16 20019 500 €</small></a></li><li><a href="/pages/ischgl/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/apartment-brandau-kappl/01.jpg')">Ischgl/Paznaun<small>Budżet grupy: ~14 20017 000 €</small></a></li><li><a href="/pages/kronplatz/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/haeuslerhof-valdaora/01.jpg')">Kronplatz<small>Budżet grupy: ~14 50017 700 €</small></a></li><li><a href="/pages/sfl/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/haus-central-ladis/01.jpg')">SFL<small>Budżet grupy: ~14 50017 900 €</small></a></li></ul> <ul class="regions"><li><a href="/pages/saalbach/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/alpenparks-sonnleiten/01.jpg')">Saalbach<small>Budżet grupy: ~16 20019 500 €</small></a></li><li><a href="/pages/ischgl/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/apartment-brandau-kappl/01.jpg')">Ischgl/Paznaun<small>Budżet grupy: ~14 20017 000 €</small></a></li><li><a href="/pages/kronplatz/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/haeuslerhof-valdaora/01.jpg')">Kronplatz<small>Budżet grupy: ~14 50017 700 €</small></a></li><li><a href="/pages/sfl/region.html" class="hero" style="background-image:linear-gradient(rgba(15,23,42,.62),rgba(15,23,42,.72)),url('/pages/img/haus-central-ladis/01.jpg')">SFL<small>Budżet grupy: ~14 50017 900 €</small></a></li></ul>

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Szablon zapytania grupowego (EN) — Ski 2027 — Skicircus Saalbach</title> <title>Szablon zapytania grupowego (EN) — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ski 2027 — cztery warianty na termin 613.02.2027 — Ski 2027 — Skicircus Saalbach</title> <title>Ski 2027 — cztery warianty na termin 613.02.2027 — Ski 2027 — wyjazd 613.02.2027</title>
<style> <style>
:root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff; :root { color-scheme: light dark; --fg:#0f172a; --muted:#64748b; --bg:#ffffff;
--line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; } --line:#e2e8f0; --accent:#0d9488; --chip:#f1f5f9; --quote:#f8fafc; }
@ -95,11 +95,19 @@ table.sortable .name { font-weight: 600; }
tr.verified td { background: rgba(13, 148, 136, .14); } tr.verified td { background: rgba(13, 148, 136, .14); }
tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); } tr.estimate td { background: rgba(100, 116, 139, .10); color: var(--muted); }
tr.estimate td.name a, tr.verified td.name a { color: var(--accent); } tr.estimate td.name a, tr.verified td.name a { color: var(--accent); }
/* zweryfikowany BRAK miejsc bije kolor statusu ceny — reguła niżej wygrywa */
tr.unavailable td { background: rgba(220, 38, 38, .16); }
tr.unavailable td.name a { text-decoration: line-through; }
td.avail { white-space: nowrap; font-weight: 600; }
.archive { margin-top: 2.5rem; }
.archive h2 { margin-bottom: .2rem; }
.archive .lead { font-size: .88rem; margin-top: .2rem; }
.legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; } .legend { font-size: .82rem; color: var(--muted); margin: .5rem 0 0; }
.legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px; .legend .box { display: inline-block; width: .8em; height: .8em; border-radius: 3px;
border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; } border: 1px solid var(--line); vertical-align: -.05em; margin-right: .25em; }
.legend .box.v { background: rgba(13, 148, 136, .35); } .legend .box.v { background: rgba(13, 148, 136, .35); }
.legend .box.e { background: rgba(100, 116, 139, .25); } .legend .box.e { background: rgba(100, 116, 139, .25); }
.legend .box.u { background: rgba(220, 38, 38, .35); }
/* miniatury w tabeli */ /* miniatury w tabeli */
td.thumb { padding: .25rem; width: 128px; } td.thumb { padding: .25rem; width: 128px; }