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
10 changes: 5 additions & 5 deletions css/ludo.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.ludo-wrap { flex: none; display: grid; place-items: center; }
.ludo-svg {
display: block; width: min(calc(100cqh - 24px), calc(100cqw - 330px), 820px); height: auto; aspect-ratio: 1;
user-select: none; -webkit-user-select: none; touch-action: manipulation; filter: drop-shadow(0 30px 50px rgba(0,0,0,.7));
user-select: none; -webkit-user-select: none; touch-action: manipulation; filter: drop-shadow(0 26px 40px rgba(0,0,0,.75)) drop-shadow(0 6px 10px rgba(0,0,0,.55));
}
.ludo-side { width: 270px; display: flex; flex-direction: column; gap: 14px; }

Expand All @@ -23,13 +23,13 @@
.lp-home i.home { background: var(--c); border-color: var(--c); }

/* the die tray (tap it to roll) and the status */
.ludo-dock { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 16px 12px; border-radius: 18px; background: radial-gradient(ellipse at 50% 30%, #1d3a2b, #0b1912); border: 1px solid rgba(255,255,255,.08); box-shadow: inset 0 0 30px rgba(0,0,0,.6); }
.ludo-dock { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 16px 12px; border-radius: 18px; background: radial-gradient(ellipse at 50% 30%, #23533a, #0d2318); border: 5px solid #4a2913; outline: 1px solid rgba(255,214,160,.22); outline-offset: -5px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.7), inset 0 6px 26px rgba(0,0,0,.75), 0 10px 22px -8px rgba(0,0,0,.8); }
.ludo-tray { --c: #fff; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 6px; border: 0; background: none; color: var(--text); font: inherit; cursor: default; border-radius: 16px; }
.ludo-tray.ready { cursor: pointer; }
.ludo-die { width: 84px; aspect-ratio: 1; border-radius: 16px; transition: box-shadow .3s; }
.ludo-die svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 8px 12px rgba(0,0,0,.6)); }
.ludo-die .ld-face { fill: #fbf7ee; stroke: var(--c); stroke-width: 3.5; }
.ludo-die circle { fill: #2a2018; }
.ludo-die svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 7px 8px rgba(0,0,0,.65)); overflow: visible; }
/* a ring in the colour of the player whose turn it is */
.ludo-die .ld-ring { fill: none; stroke: var(--c); stroke-width: 2.5; opacity: .9; }
.ludo-die.rolling { visibility: hidden; }
.ludo-tray.ready .ludo-die { animation: ludo-ready 1.4s ease-in-out infinite; }
@keyframes ludo-ready { 50% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--c) 0%, transparent), 0 0 30px color-mix(in srgb, var(--c) 70%, transparent); transform: translateY(-3px); } }
Expand Down
8 changes: 4 additions & 4 deletions css/tabla.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@
width: min(100%, calc((100cqh - 128px) * 980 / 760), 1100px);
height: auto; max-height: 100%;
border-radius: 18px;
box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .8), 0 0 0 1px rgba(255,255,255,.06);
box-shadow: 0 34px 70px -18px rgba(0, 0, 0, .9), 0 10px 22px -8px rgba(0, 0, 0, .7), 0 0 0 1px rgba(0, 0, 0, .6);
touch-action: manipulation; user-select: none; -webkit-user-select: none;
}
.tb-svg.rot { width: min(100%, calc((100cqh - 128px) * 760 / 980), 640px); }
.tb-svg.rot .tb-num, .tb-svg.rot .tb-count { transform-box: fill-box; transform-origin: center; transform: rotate(-90deg); }
/* black sees the board flipped vertically – the labels are flipped back */
.tb-svg.flip .tb-num, .tb-svg.flip .tb-count { transform-box: fill-box; transform-origin: center; transform: scale(1, -1); }
.tb-svg.rot.flip .tb-num, .tb-svg.rot.flip .tb-count { transform: scale(1, -1) rotate(-90deg); }
.tb-num { font-size: 12px; font-weight: 700; fill: rgba(255, 236, 200, .45); text-anchor: middle; font-family: var(--font); }
.tb-count { font-size: 22px; font-weight: 800; text-anchor: middle; font-family: var(--font); pointer-events: none; }
.tb-num { font-size: 11px; font-weight: 700; fill: rgba(255, 226, 180, .55); text-anchor: middle; font-family: var(--font); }
.tb-count { font-size: 22px; font-weight: 800; text-anchor: middle; font-family: var(--font); pointer-events: none; paint-order: stroke; stroke: rgba(0, 0, 0, .18); stroke-width: 3px; }
.tb-ck { filter: url(#sh); }
.tb-src { fill: rgba(255, 217, 120, .18); stroke: #ffd978; stroke-width: 5; stroke-dasharray: 10 6; animation: tb-spin 6s linear infinite; transform-box: fill-box; transform-origin: center; pointer-events: none; }
.tb-src.sel { stroke: #ffd978; stroke-width: 6; stroke-dasharray: none; filter: drop-shadow(0 0 8px rgba(255, 217, 120, .9)); }
.tb-dst { fill: rgba(255, 217, 120, .45); stroke: #ffd978; stroke-width: 5; animation: tb-glow 1.2s ease-in-out infinite alternate; }
.tb-die { transition: opacity .25s; filter: url(#sh); transform-box: fill-box; transform-origin: center; }
.tb-die { transition: opacity .25s; filter: drop-shadow(0 3px 2.5px rgba(20, 8, 0, .6)); transform-box: fill-box; transform-origin: center; }
.tb-die.used { opacity: .3; }
.tb-die.pop { animation: tb-pop .35s cubic-bezier(.3,1.5,.5,1) both; }
@keyframes tb-pop { from { transform: scale(0); opacity: 0; } }
Expand Down
33 changes: 33 additions & 0 deletions js/games/dieface.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// The resting die (SVG, 58×58 box): the same look as the 3D die that lands on it –
// rounded ivory body, bevelled edge, engraved pips.
export const DIE_PIPS = {
1: [[29, 29]],
2: [[16, 16], [42, 42]],
3: [[15, 15], [29, 29], [43, 43]],
4: [[16, 16], [42, 16], [16, 42], [42, 42]],
5: [[16, 16], [42, 16], [29, 29], [16, 42], [42, 42]],
6: [[16, 15], [42, 15], [16, 29], [42, 29], [16, 43], [42, 43]],
};

// Gradients for the dice; id – a prefix that keeps the ids unique per <svg>.
export function dieDefs(id = 'die') {
return `
<linearGradient id="${id}Lb" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#fffefa"/><stop offset=".55" stop-color="#f4ecd9"/><stop offset="1" stop-color="#cdbf9f"/></linearGradient>
<radialGradient id="${id}Lf" cx=".36" cy=".3" r=".85"><stop offset="0" stop-color="#ffffff"/><stop offset=".6" stop-color="#faf4e6"/><stop offset="1" stop-color="#eadfc6"/></radialGradient>
<radialGradient id="${id}Lp" cx=".4" cy=".34" r=".75"><stop offset="0" stop-color="#050302"/><stop offset=".65" stop-color="#231912"/><stop offset="1" stop-color="#4d3c2e"/></radialGradient>
<linearGradient id="${id}Db" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#6a4048"/><stop offset=".5" stop-color="#2c171c"/><stop offset="1" stop-color="#0c0507"/></linearGradient>
<radialGradient id="${id}Df" cx=".36" cy=".3" r=".85"><stop offset="0" stop-color="#553138"/><stop offset=".6" stop-color="#2e181d"/><stop offset="1" stop-color="#1b0c10"/></radialGradient>
<radialGradient id="${id}Dp" cx=".4" cy=".34" r=".75"><stop offset="0" stop-color="#cdbd98"/><stop offset=".6" stop-color="#f1e6cb"/><stop offset="1" stop-color="#fffaf0"/></radialGradient>
<linearGradient id="${id}Rim" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#000" stop-opacity=".55"/><stop offset=".5" stop-color="#000" stop-opacity="0"/><stop offset="1" stop-color="#fff" stop-opacity=".75"/></linearGradient>
<linearGradient id="${id}Gl" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".55"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient>`;
}

// SVG markup of one die face showing `value` (0 – a blank face).
export function dieMarkup(value, dark = false, id = 'die') {
const k = dark ? 'D' : 'L';
const pips = (DIE_PIPS[value] || []).map(([x, y]) =>
`<circle cx="${x}" cy="${y}" r="5.7" fill="url(#${id}${k}p)"/><circle cx="${x}" cy="${y}" r="5.7" fill="none" stroke="url(#${id}Rim)" stroke-width="1.1" opacity="${dark ? 0.55 : 0.9}"/>`).join('');
return `<rect x=".5" y=".5" width="57" height="57" rx="12.5" fill="url(#${id}${k}b)" stroke="${dark ? '#050203' : '#b3a37f'}" stroke-width="1"/>
<rect x="3.6" y="3.2" width="50.8" height="50.8" rx="10" fill="url(#${id}${k}f)"/>
<rect x="6" y="4.6" width="46" height="13" rx="6.5" fill="url(#${id}Gl)" opacity="${dark ? 0.22 : 0.5}"/>${pips}`;
}
Loading
Loading