Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion calendarium/datetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def translation_session_key(language):
TRANSLATION_LABELS = {
'kjv': 'King James Version',
'lxx2012-web': 'LXX2012 & WEB',
'douay-rheims': 'Douay-Rheims (Challoner, 1899)',
'douay-rheims': 'Douay-Rheims',
'rccv': 'Romanian Corrected Cornilescu Version',
'srp1865': 'Serbian (Karadžić/Daničić, 1865)',
}
Expand Down
12 changes: 6 additions & 6 deletions calendarium/templates/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
{% block extra_nav %}
<div class="page-nav-row">
<div class="day-nav">
<a class="cal-nav" href="{% url "calendar" tradition=tradition cal=cal year=previous_month.year month=previous_month.month %}" {% if previous_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "calendar" tradition=tradition cal=cal year=previous_month.year month=previous_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">&larr; {{ previous_month|date:"F" }}</a>
<a class="cal-nav" href="{% url "calendar" tradition=tradition cal=cal year=next_month.year month=next_month.month %}" {% if next_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "calendar" tradition=tradition cal=cal year=next_month.year month=next_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">{{ next_month|date:"F" }} &rarr;</a>
<a class="cal-nav" href="{% url "calendar" tradition=tradition cal=cal year=previous_month.year month=previous_month.month %}" {% if previous_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "calendar" tradition=tradition cal=cal year=previous_month.year month=previous_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">&larr; {{ previous_month|date:"F" }}</a>
<a class="cal-nav" href="{% url "calendar" tradition=tradition cal=cal year=next_month.year month=next_month.month %}" {% if next_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "calendar" tradition=tradition cal=cal year=next_month.year month=next_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">{{ next_month|date:"F" }} &rarr;</a>
</div>

<div class="toggle-row" hx-params="none">
<div class="segmented-control">
<label title="OCA, ROCOR"><input type="radio" name="tradition" value="slavic" {% if tradition == "slavic" %}checked=""{% endif %} hx-get="{% url "calendar" tradition="slavic" cal=cal year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Slavic</label>
<label title="Antiochian, Greek Archdiocese"><input type="radio" name="tradition" value="greek" {% if tradition == "greek" %}checked=""{% endif %} hx-get="{% url "calendar" tradition="greek" cal=cal year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Greek</label>
<label title="OCA, ROCOR"><input type="radio" name="tradition" value="slavic" {% if tradition == "slavic" %}checked=""{% endif %} hx-get="{% url "calendar" tradition="slavic" cal=cal year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Slavic</label>
<label title="Antiochian, Greek Archdiocese"><input type="radio" name="tradition" value="greek" {% if tradition == "greek" %}checked=""{% endif %} hx-get="{% url "calendar" tradition="greek" cal=cal year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Greek</label>
</div>
<div class="segmented-control">
<label><input type="radio" name="calendar" value="gregorian" {% if cal == "gregorian" %}checked=""{% endif %} hx-get="{% url "calendar" tradition=tradition cal="gregorian" year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Gregorian</label>
<label><input type="radio" name="calendar" value="julian" {% if cal == "julian" %}checked=""{% endif %} hx-get="{% url "calendar" tradition=tradition cal="julian" year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Julian</label>
<label><input type="radio" name="calendar" value="gregorian" {% if cal == "gregorian" %}checked=""{% endif %} hx-get="{% url "calendar" tradition=tradition cal="gregorian" year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Gregorian</label>
<label><input type="radio" name="calendar" value="julian" {% if cal == "julian" %}checked=""{% endif %} hx-get="{% url "calendar" tradition=tradition cal="julian" year=this_month.year month=this_month.month %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Julian</label>
</div>
</div>
</div>
Expand Down
16 changes: 8 additions & 8 deletions calendarium/templates/readings.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@
{% block extra_nav %}
<div class="page-nav-row">
<div class="day-nav">
<a class="cal-nav" href="{% url "readings" tradition=tradition cal=cal year=previous_date.year month=previous_date.month day=previous_date.day %}" {% if previous_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "readings" tradition=tradition cal=cal year=previous_date.year month=previous_date.month day=previous_date.day %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">&larr; Previous Day</a>
<a class="cal-nav" href="{% url "index" %}" hx-get="{% url "index" %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Today</a>
<a class="cal-nav" href="{% url "readings" tradition=tradition cal=cal year=next_date.year month=next_date.month day=next_date.day %}" {% if next_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "readings" tradition=tradition cal=cal year=next_date.year month=next_date.month day=next_date.day %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Next Day &rarr;</a>
<a class="cal-nav" href="{% url "readings" tradition=tradition cal=cal year=previous_date.year month=previous_date.month day=previous_date.day %}" {% if previous_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "readings" tradition=tradition cal=cal year=previous_date.year month=previous_date.month day=previous_date.day %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">&larr; Previous Day</a>
<a class="cal-nav" href="{% url "index" %}" hx-get="{% url "index" %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Today</a>
<a class="cal-nav" href="{% url "readings" tradition=tradition cal=cal year=next_date.year month=next_date.month day=next_date.day %}" {% if next_nofollow %}rel="nofollow"{% endif %} hx-get="{% url "readings" tradition=tradition cal=cal year=next_date.year month=next_date.month day=next_date.day %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Next Day &rarr;</a>
</div>

<div class="toggle-row" hx-params="none">
<div class="segmented-control">
<label title="OCA, ROCOR"><input type="radio" name="tradition" value="slavic" {% if tradition == "slavic" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition="slavic" cal=cal translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition="slavic" cal=cal year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Slavic</label>
<label title="Antiochian, Greek Archdiocese"><input type="radio" name="tradition" value="greek" {% if tradition == "greek" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition="greek" cal=cal translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition="greek" cal=cal year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Greek</label>
<label title="OCA, ROCOR"><input type="radio" name="tradition" value="slavic" {% if tradition == "slavic" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition="slavic" cal=cal translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition="slavic" cal=cal year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Slavic</label>
<label title="Antiochian, Greek Archdiocese"><input type="radio" name="tradition" value="greek" {% if tradition == "greek" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition="greek" cal=cal translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition="greek" cal=cal year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Greek</label>
</div>
<div class="segmented-control">
<label><input type="radio" name="calendar" value="gregorian" {% if cal == "gregorian" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition=tradition cal="gregorian" translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition=tradition cal="gregorian" year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Gregorian</label>
<label><input type="radio" name="calendar" value="julian" {% if cal == "julian" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition=tradition cal="julian" translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition=tradition cal="julian" year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML" hx-push-url="true">Julian</label>
<label><input type="radio" name="calendar" value="gregorian" {% if cal == "gregorian" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition=tradition cal="gregorian" translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition=tradition cal="gregorian" year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Gregorian</label>
<label><input type="radio" name="calendar" value="julian" {% if cal == "julian" %}checked=""{% endif %} hx-get="{% if translation %}{% url "readings" tradition=tradition cal="julian" translation=translation year=date.year month=date.month day=date.day %}{% else %}{% url "readings" tradition=tradition cal="julian" year=date.year month=date.month day=date.day %}{% endif %}" hx-select="#orthocal-content" hx-target="#orthocal-content" hx-swap="outerHTML transition:true" hx-push-url="true">Julian</label>
</div>
</div>
</div>
Expand Down Expand Up @@ -100,7 +100,7 @@ <h1>Scripture Readings&nbsp;({{ translation_label }})</h1>
{% if day.language == "en" %}
<p class="translation-picker">
<label for="translation-select">Translation:
<select id="translation-select" hx-get="" hx-on::config-request="event.detail.path = this.value" hx-select="#scripture-readings" hx-target="#scripture-readings" hx-swap="outerHTML" hx-push-url="true">
<select id="translation-select" hx-get="" hx-on::config-request="event.detail.path = this.value" hx-select="#scripture-readings" hx-target="#scripture-readings" hx-swap="outerHTML transition:true" hx-push-url="true">
{% for value, label in translation_choices %}
<option value="{% url "readings" tradition=tradition cal=cal translation=value year=date.year month=date.month day=date.day %}" {% if translation == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
Expand Down
109 changes: 108 additions & 1 deletion orthocal/static/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ html {
font-size: 20px;
font-family: var(--font-serif);
overflow-y: auto;
/* Without this, a page short enough to need no vertical scrollbar is a
few pixels wider (viewport-wise) than one that does, which shifts the
centered, percentage-width topbar horizontally between pages -- most
visible on classic (non-overlay) scrollbars, e.g. Windows/Linux.
Reserving the gutter unconditionally keeps the available width (and
so the topbar's position) constant regardless of page height. */
scrollbar-gutter: stable;
}
/* Scripture-reference and commemoration links (e.g. "2 Corinthians 7.10-16")
jump to their #reading-N/#commemoration-N passage further down the same
page -- smooth-scrolling that jump reads much better than a hard cut. */
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}
body {
margin: 0;
Expand Down Expand Up @@ -261,6 +276,19 @@ h1, h2, h3, h4 {
color: var(--color-text-strong);
text-shadow: var(--shadow-hover-text);
}
/* Marks which top-level section the current page belongs to. Applied to
the <a> itself for direct nav items, and to the submenu's <summary> (via
.has-active, set server-side alongside the rest of the nav) for pages
that live inside "Integrations"/"More" -- otherwise a page like About
would have no visible indicator at all while its disclosure is closed. */
.topbar-inner > nav a[aria-current="page"],
.topbar-inner > nav summary.has-active {
color: var(--color-text-strong);
text-decoration: underline;
text-decoration-color: var(--color-accent);
text-decoration-thickness: 2px;
text-underline-offset: 0.3em;
}

/* Submenu (e.g. "Developers") -- a native <details>/<summary> disclosure
rather than a CSS :hover flyout, so it works identically (click to open,
Expand All @@ -284,12 +312,18 @@ h1, h2, h3, h4 {
display: none;
}
.topbar-inner > nav summary::after {
/* A single glyph rotated in place, rather than swapping between "\25be"
and "\25b4" on open -- those two characters have very slightly
different advance widths, which shifted the whole (flex-end
justified) nav row by a pixel or two whenever a submenu toggled. */
content: " \25be";
display: inline-block;
font-size: 0.7em;
vertical-align: middle;
transition: transform 0.15s ease;
}
.topbar-inner > nav details[open] summary::after {
content: " \25b4";
transform: rotate(180deg);
}
.topbar-inner > nav summary:hover {
color: var(--color-text-strong);
Expand All @@ -314,6 +348,45 @@ h1, h2, h3, h4 {
box-shadow: var(--shadow-dropdown);
z-index: 20;
}
/* <details> content becomes visible/hidden as a discrete step (there's no
cross-browser-reliable way yet to animate that transition itself), but a
plain CSS animation still replays from its "from" state every time the
content is un-hidden -- so a fade+slide-in plays whenever the browser
actually un-hides it on open. The reverse (dropdown-out, via the
.closing class) is driven by base.html's script, which defers actually
closing the <details> until this animation finishes, so the content
stays rendered (and animatable) for the moment it takes to fade out.
The .closing rule is listed after the [open] one so it wins the tie --
both match while a close is in flight, since .closing is added before
[open] is removed. */
@media (prefers-reduced-motion: no-preference) {
.topbar-inner > nav details[open] ul {
animation: dropdown-in 0.15s ease;
}
.topbar-inner > nav details ul.closing {
animation: dropdown-out 0.15s ease;
}
}
@keyframes dropdown-in {
from {
opacity: 0;
transform: translateY(-6px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes dropdown-out {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-6px);
}
}
.topbar-inner > nav details ul li {
display: block;
text-transform: lowercase;
Expand Down Expand Up @@ -377,6 +450,16 @@ h1, h2, h3, h4 {
.topbar-inner > nav.nav-open > ul {
display: flex;
}
@media (prefers-reduced-motion: no-preference) {
.topbar-inner > nav.nav-open > ul {
animation: dropdown-in 0.15s ease;
}
/* See the .closing comment above the desktop submenu's dropdown-out
rule -- same deferred-close mechanism, driven by the same script. */
.topbar-inner > nav > ul.closing {
animation: dropdown-out 0.15s ease;
}
}
.topbar-inner > nav > ul > li {
box-sizing: border-box;
width: 100%;
Expand Down Expand Up @@ -553,6 +636,30 @@ main#orthocal iframe {
border: 1px solid var(--color-border-light);
border-radius: 3px;
}
/* The translation <select> and the tradition/calendar toggles all swap
some part of #orthocal-content via htmx's transition:true modifier,
which wraps the swap in the View Transitions API when the browser
supports it (a no-op fallback -- an instant swap, same as before --
everywhere else). Giving the region its own view-transition-name makes
it crossfade as its own isolated group; without this it would still
animate, but as part of the default ::view-transition-old/new(root)
group, which also captures (and so crossfades) the rest of the page --
topbar included -- around it for no reason. Disabling the root group's
own animation leaves only #orthocal-content animating. Named on this
outer element rather than on the narrower #scripture-readings (which
the translation swap alone actually touches) so a nested element is
never independently named while its ancestor also is -- the View
Transitions spec extracts named elements from their ancestor's capture,
which would otherwise split one swap into two competing transitions. */
@media (prefers-reduced-motion: no-preference) {
#orthocal-content {
view-transition-name: orthocal-content;
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
}
}
#orthocal-content > header {
position: relative;
/* z-index establishes this header as its own stacking context, so the
Expand Down
Loading