// RACI-Konsolen-Board — SLC-Workshop Tabletop · Einheiten: mm
// Quadratisches Premium-Board: zentrale Acryl-Chip-Mulde (Stations-/Gate-ID),
// 10 Figurenmulden im Ring, gruppiert in 4 RACI-Sektoren (R3 · A1 · C4 · I2),
// erhabene Trennstege, gravierte Sektor-Buchstaben + Wörter, gravierte Rand-Linie,
// stehender Action-Card-Halter (60x90) hinten.
// Druck: 6x in den Phasenfarben (5 Phasen + Gate-Rot). Einfarbig je Board (Filament).

/* [Board] */
board_w   = 210;
board_d   = 210;
base_h    = 10;
corner_r  = 8;
cut_corner = 22;     // gefaste Ecke (vorne rechts), Optik

/* [Dial / Mitte] */
dial_cx   = 0;
dial_cy   = -15;     // Scheibe etwas nach vorn -> Platz fuer Card-Halter hinten
chip_d    = 40.6;    // Acryl-Chip Ø40 + Spiel
chip_dep  = 1.8;     // Chip 2 mm steht ~0,2 vor (greifbar)
notch_r   = 6;       // Greifkerbe

/* [Sockel] — Figuren-Sockel Ø24,5 -> Mulde Ø25,3 */
sock_d    = 25.3;
sock_dep  = 1.5;
sock_lead = 0.6;
ring_R    = 48;      // Radius Sockelkreis (Mitte-Mitte)

/* [Sektor-Trennstege] */
ridge_h   = 2.6;
ridge_w   = 3.2;

/* [Gravur] */
let_size  = 11;      // grosse R/A/C/I
let_dep   = 0.9;
word_size = 5;       // RESPONSIBLE ...
word_dep  = 0.7;
border_inset = 7;
border_w  = 1.6;
border_dep= 0.7;

/* [Action-Card-Halter] (Karte 60x90, steht leicht nach hinten geneigt) */
card_w    = 84;      // Plinthen-Breite
card_block_d = 22;
card_block_h = 16;
card_cy   = 78;      // Position hinten
slot_w    = 63;      // Kartenbreite 60 + Spiel
slot_t    = 4;       // Kartendicke + Spiel
slot_tilt = 12;      // Grad Neigung nach hinten

$fn = 64;

// 10 Sockel: Winkel ab oben (90°) im Uhrzeigersinn, 36° Schritt.
// Gruppen: A=[0]  C=[1..4]  I=[5,6]  R=[7,8,9]
function ang(i) = 90 - i*36;
GROUP_A = [0];
GROUP_C = [1,2,3,4];
GROUP_I = [5,6];
GROUP_R = [7,8,9];
// Sektor-Mittenwinkel (fuer Buchstaben) und Grenzwinkel (fuer Trennstege)
A_mid = 90; C_mid = 0; I_mid = -108; R_mid = 162;
DIVIDERS = [72, -72, -144, 108];

module rrect(w, d, h, r) {
    linear_extrude(h) offset(r) offset(-r) square([w, d], center=true);
}

module base_slab() {
    difference() {
        rrect(board_w, board_d, base_h, corner_r);
        // gefaste Ecke vorne rechts
        translate([board_w/2, -board_d/2, -1])
            rotate([0,0,45]) cube([cut_corner, cut_corner, base_h+2], center=true);
    }
}

module figure_socket(a, r=ring_R) {
    x = dial_cx + r*cos(a); y = dial_cy + r*sin(a);
    translate([x, y, base_h - sock_dep]) {
        cylinder(d=sock_d, h=sock_dep + 0.2);
        translate([0,0,sock_dep - sock_lead])
            cylinder(d1=sock_d, d2=sock_d + 2*sock_lead, h=sock_lead + 0.1);
    }
}

module chip_well() {
    translate([dial_cx, dial_cy, base_h - chip_dep]) cylinder(d=chip_d, h=chip_dep + 0.2);
    // Greifkerbe Richtung vorn
    translate([dial_cx, dial_cy - chip_d/2, base_h - chip_dep])
        cylinder(r=notch_r, h=chip_dep + 0.2);
}

module grooves() {  // konzentrische Deko-Rillen im Innenfeld
    for (rr = [23 : 2 : 34])
        translate([dial_cx, dial_cy, base_h - 0.5])
            linear_extrude(0.6)
                difference() { circle(r=rr); circle(r=rr-0.8); }
}

module dividers() {
    for (a = DIVIDERS) {
        ri = chip_d/2 + 3; ro = ring_R + sock_d/2 + 4;
        translate([dial_cx, dial_cy, base_h])
            rotate([0,0,a])
                translate([(ri+ro)/2, 0, ridge_h/2])
                    cube([ro-ri, ridge_w, ridge_h], center=true);
    }
}

module letter(a, ch) {
    rl = ring_R + 13;
    x = dial_cx + rl*cos(a); y = dial_cy + rl*sin(a);
    translate([x, y, base_h - let_dep])
        linear_extrude(let_dep + 0.1)
            text(ch, size=let_size, halign="center", valign="center",
                 font="DejaVu Sans:style=Bold");
}

module word(txt, x, y, rot) {
    translate([x, y, base_h - word_dep])
        rotate([0,0,rot])
            linear_extrude(word_dep + 0.1)
                text(txt, size=word_size, halign="center", valign="center");
}

module border_channel() {
    translate([0,0, base_h - border_dep])
        linear_extrude(border_dep + 0.1)
            difference() {
                offset(-border_inset) offset(corner_r) offset(-corner_r) square([board_w, board_d], center=true);
                offset(-border_inset-border_w) offset(corner_r) offset(-corner_r) square([board_w, board_d], center=true);
            }
}

module card_block() {
    translate([0, card_cy, 0]) rrect(card_w, card_block_d, base_h + card_block_h, 4);
}
module card_slot() {
    // oben offener Schlitz, leicht nach HINTEN geneigt; Boden bleibt ~3 mm stehen
    translate([0, card_cy, 22])
        rotate([-slot_tilt, 0, 0])
            cube([slot_w, slot_t, 38], center=true);
}

module raci_board() {
    difference() {
        union() {
            base_slab();
            dividers();
            card_block();
        }
        chip_well();
        grooves();
        for (i=[0:9]) figure_socket(ang(i));
        // grosse Buchstaben
        letter(A_mid, "A");
        letter(C_mid, "C");
        letter(I_mid, "I");
        letter(R_mid, "R");
        // Woerter
        word("RESPONSIBLE", -ring_R-29, dial_cy+6, 90);
        word("CONSULTED",    ring_R+29, dial_cy+6, -90);
        word("INFORMED", dial_cx, dial_cy - ring_R - 30, 0);
        word("ACCOUNTABLE", dial_cx, card_cy - card_block_d/2 - 7, 0);
        border_channel();
        card_slot();
    }
}

raci_board();

echo(board=[board_w, board_d, base_h], sockets=10, raci="R3 A1 C4 I2",
     chip_well=chip_d, sock=sock_d);
