feat(website): randomise which logo comes first on /logo/ per visit
Hugo sorts map keys, so `range (dict "m" … "r" …)` always put M first and gave it the "first thing on the page" vote. The template now ranges over an ordered list (front-matter `order:` can pin it), and a tiny inline script on poll pages coin-flips the visual order before first paint, applied via CSS `order` on every M/R pair and remembered in sessionStorage so a reload or a vote doesn't shuffle the page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y8kPxizsExc95ZhvfJmaCw
This commit is contained in:
parent
c3c59b4bea
commit
722dac4843
3 changed files with 25 additions and 12 deletions
|
|
@ -559,4 +559,12 @@ main.container {
|
||||||
.home-poll:hover { border-color: var(--accent); }
|
.home-poll:hover { border-color: var(--accent); }
|
||||||
.home-poll .pm { height: 1.1rem; width: auto; color: var(--accent); }
|
.home-poll .pm { height: 1.1rem; width: auto; color: var(--accent); }
|
||||||
.home-poll .pm + .pm { color: #af6428; }
|
.home-poll .pm + .pm { color: #af6428; }
|
||||||
|
/* Random left/right per visit — data-logo-order is set in head.html before first paint.
|
||||||
|
Every pair container is a grid/flex, so `order` swaps the columns without touching the DOM. */
|
||||||
|
[data-logo-order="rm"] .poll-card[data-choice="m"],
|
||||||
|
[data-logo-order="rm"] .show-cell.show-cell--m,
|
||||||
|
[data-logo-order="rm"] .poll-final-card[data-choice="m"],
|
||||||
|
[data-logo-order="mr"] .poll-card[data-choice="r"],
|
||||||
|
[data-logo-order="mr"] .show-cell.show-cell--r,
|
||||||
|
[data-logo-order="mr"] .poll-final-card[data-choice="r"] { order: 1; }
|
||||||
@media (prefers-reduced-motion: reduce) { .poll-bar i, .poll-btn { transition: none; } }
|
@media (prefers-reduced-motion: reduce) { .poll-bar i, .poll-btn { transition: none; } }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
<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">
|
||||||
<script>document.documentElement.classList.replace('no-js','js');</script>
|
<script>document.documentElement.classList.replace('no-js','js');</script>
|
||||||
<title>{{ if .IsHome }}{{ site.Title }} — {{ site.Params.description }}{{ else }}{{ .Title }} · {{ site.Title }}{{ end }}</title>
|
{{ if eq .Type "poll" }}{{/* Coin-flip which mark sits left/first, so neither side collects the
|
||||||
|
"first thing on the page" votes. Decided before first paint (no reflow), applied by CSS `order`,
|
||||||
|
and kept for the tab session so a reload or a vote doesn't shuffle the page under the visitor. */}}
|
||||||
|
<script>(function(){var k='furtka-logo-order',o=null;try{o=sessionStorage.getItem(k)}catch(e){}if(o!=='mr'&&o!=='rm'){o=Math.random()<0.5?'mr':'rm';try{sessionStorage.setItem(k,o)}catch(e){}}document.documentElement.setAttribute('data-logo-order',o)})();</script>
|
||||||
|
{{ end }}<title>{{ if .IsHome }}{{ site.Title }} — {{ site.Params.description }}{{ else }}{{ .Title }} · {{ site.Title }}{{ end }}</title>
|
||||||
<meta name="description" content="{{ with .Params.description }}{{ . }}{{ else }}{{ site.Params.description }}{{ end }}">
|
<meta name="description" content="{{ with .Params.description }}{{ . }}{{ else }}{{ site.Params.description }}{{ end }}">
|
||||||
<meta name="theme-color" content="#f7f6f3" media="(prefers-color-scheme: light)">
|
<meta name="theme-color" content="#f7f6f3" media="(prefers-color-scheme: light)">
|
||||||
<meta name="theme-color" content="#0d0d0f" media="(prefers-color-scheme: dark)">
|
<meta name="theme-color" content="#0d0d0f" media="(prefers-color-scheme: dark)">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
{{- $p := .Params -}}
|
{{- $p := .Params -}}
|
||||||
{{- $M := site.Data.logo.m -}}
|
{{/* Display order of the two marks; flip via `order: [r, m]` in front matter so neither
|
||||||
{{- $R := site.Data.logo.r -}}
|
side gets the "first thing on the page" advantage for the whole poll. */}}
|
||||||
|
{{- $order := $p.order | default (slice "m" "r") -}}
|
||||||
{{- $s := $p.show -}}
|
{{- $s := $p.show -}}
|
||||||
<article class="poll" data-poll="{{ $p.poll }}" data-api="/api/poll/{{ $p.poll }}">
|
<article class="poll" data-poll="{{ $p.poll }}" data-api="/api/poll/{{ $p.poll }}">
|
||||||
<header class="page-header">
|
<header class="page-header">
|
||||||
|
|
@ -12,7 +13,7 @@
|
||||||
|
|
||||||
{{/* ── Quick vote ─────────────────────────────────────────── */}}
|
{{/* ── Quick vote ─────────────────────────────────────────── */}}
|
||||||
<div class="poll-grid" id="vote">
|
<div class="poll-grid" id="vote">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
{{ $c := index $p $k }}
|
{{ $c := index $p $k }}
|
||||||
<section class="poll-card" data-choice="{{ $k }}" aria-labelledby="poll-{{ $k }}-title">
|
<section class="poll-card" data-choice="{{ $k }}" aria-labelledby="poll-{{ $k }}-title">
|
||||||
<div class="poll-art poll-art--{{ $k }}">{{ $d.display | safeHTML }}</div>
|
<div class="poll-art poll-art--{{ $k }}">{{ $d.display | safeHTML }}</div>
|
||||||
|
|
@ -38,7 +39,7 @@
|
||||||
<h2 class="show-h">{{ $s.sizes }}</h2>
|
<h2 class="show-h">{{ $s.sizes }}</h2>
|
||||||
<p class="show-p">{{ $s.sizes_text }}</p>
|
<p class="show-p">{{ $s.sizes_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<div class="sizes">
|
<div class="sizes">
|
||||||
|
|
@ -57,7 +58,7 @@
|
||||||
<h2 class="show-h">{{ $s.name }}</h2>
|
<h2 class="show-h">{{ $s.name }}</h2>
|
||||||
<p class="show-p">{{ $s.name_text }}</p>
|
<p class="show-p">{{ $s.name_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<div class="lock lock-h">{{ $d.lockup_h | safeHTML }}</div>
|
<div class="lock lock-h">{{ $d.lockup_h | safeHTML }}</div>
|
||||||
|
|
@ -71,7 +72,7 @@
|
||||||
<h2 class="show-h">{{ $s.browser }}</h2>
|
<h2 class="show-h">{{ $s.browser }}</h2>
|
||||||
<p class="show-p">{{ $s.browser_text }}</p>
|
<p class="show-p">{{ $s.browser_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<div class="mock">
|
<div class="mock">
|
||||||
|
|
@ -89,7 +90,7 @@
|
||||||
<h2 class="show-h">{{ $s.phone }}</h2>
|
<h2 class="show-h">{{ $s.phone }}</h2>
|
||||||
<p class="show-p">{{ $s.phone_text }}</p>
|
<p class="show-p">{{ $s.phone_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<div class="tiles"><img src="/img/logo/{{ $k }}/tile.png" width="96" height="96" alt=""><img src="/img/logo/{{ $k }}/tile-round.png" width="96" height="96" alt=""></div>
|
<div class="tiles"><img src="/img/logo/{{ $k }}/tile.png" width="96" height="96" alt=""><img src="/img/logo/{{ $k }}/tile-round.png" width="96" height="96" alt=""></div>
|
||||||
|
|
@ -102,7 +103,7 @@
|
||||||
<h2 class="show-h">{{ $s.box }}</h2>
|
<h2 class="show-h">{{ $s.box }}</h2>
|
||||||
<p class="show-p">{{ $s.box_text }}</p>
|
<p class="show-p">{{ $s.box_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<pre class="term"><i>{{ $d.banner }}</i>
|
<pre class="term"><i>{{ $d.banner }}</i>
|
||||||
|
|
@ -118,7 +119,7 @@
|
||||||
<h2 class="show-h">{{ $s.shared }}</h2>
|
<h2 class="show-h">{{ $s.shared }}</h2>
|
||||||
<p class="show-p">{{ $s.shared_text }}</p>
|
<p class="show-p">{{ $s.shared_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<img class="shot" src="/img/logo/{{ $k }}/social.png" width="600" height="315" alt="">
|
<img class="shot" src="/img/logo/{{ $k }}/social.png" width="600" height="315" alt="">
|
||||||
|
|
@ -131,7 +132,7 @@
|
||||||
<h2 class="show-h">{{ $s.colour }}</h2>
|
<h2 class="show-h">{{ $s.colour }}</h2>
|
||||||
<p class="show-p">{{ $s.colour_text }}</p>
|
<p class="show-p">{{ $s.colour_text }}</p>
|
||||||
<div class="show-pair">
|
<div class="show-pair">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="show-cell show-cell--{{ $k }}">
|
<div class="show-cell show-cell--{{ $k }}">
|
||||||
<span class="show-tag">{{ index $p $k "short" }}</span>
|
<span class="show-tag">{{ index $p $k "short" }}</span>
|
||||||
<div class="grounds">
|
<div class="grounds">
|
||||||
|
|
@ -150,7 +151,7 @@
|
||||||
<section class="poll-final">
|
<section class="poll-final">
|
||||||
<h2 class="show-h">{{ $s.final }}</h2>
|
<h2 class="show-h">{{ $s.final }}</h2>
|
||||||
<div class="poll-final-row">
|
<div class="poll-final-row">
|
||||||
{{ range $k, $d := (dict "m" $M "r" $R) }}
|
{{ range $k := $order }}{{ $d := index site.Data.logo $k }}
|
||||||
<div class="poll-final-card" data-choice="{{ $k }}">
|
<div class="poll-final-card" data-choice="{{ $k }}">
|
||||||
<span class="poll-final-mark show-cell--{{ $k }}">{{ $d.flat | safeHTML }}</span>
|
<span class="poll-final-mark show-cell--{{ $k }}">{{ $d.flat | safeHTML }}</span>
|
||||||
<button type="button" class="poll-btn" data-vote="{{ $k }}">{{ $p.labels.vote }} — {{ index $p $k "short" }}</button>
|
<button type="button" class="poll-btn" data-vote="{{ $k }}">{{ $p.labels.vote }} — {{ index $p $k "short" }}</button>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue